开发者

Is there a better way to set lots of required properties than sending as parameters in a Constructor?

I have a class that in order to do it's job needs to have 8 different property values set. I want to make sure that all 8 properties are set before trying to execute a method. I currently have all the parameters passed in and set via开发者_如何学C the constructor. Is there a better way to do this?


You can allow the object to be created without specifying values for all the properties and then the method would throw an InvalidOperationException if called before the object state is valid for the method call to execute, which in this case would mean that all 8 properties would have valid values.

This way you give more flexibility to the consumer. It can create a new instance at one moment, set it's properties at another and only then call the method. This is a "pattern" that is used through the .NET codebase and to which developers are already used.


Update:

This also simplifies things if you're adding other methods that don't need the full set of properties to be initialized. Yes we could add another constructor overload with the new set of properties, but what if we have 2 methods that both need one property of the same type to be initialized? This is not solvable by using constructor overloads.


In my opinion if a class requires these 8 objects in order to function then they should be passed into the constructor and by no other means. I'm a big fan of dependency injection anyway, but this method also allows for better unit testing by passing in mocked objects and such.


you could consolidate the parameters into a Parameter Object and just pass that instead.


If you were using this class from XAML you would make all 8 properties individually settable and throw an exception if somebody tries to execute a method without them all set. It's also possible that you would want to "freeze" the object once a method was called and throw an exception if somebody tries to set a property on a "frozen" object.

I'm not going to pass judgement on which method is better, though.


A constructor is the only way to do it at compile time. The other option would be to throw an exception if not all the parameters have been set.


Give them default values? Maybe you can give a bit more of the context to let us help you!


Use setter in the properties. When property is used by the method and it is not set already, setter would do it for you. This is not the recommended approach thogh but might be needed in some situations.

Some thing similar would work

    Class SomeClass        
    {
     string name;
     string Name 
     { 
       set 
       {
        if (name  == null) 
         name  = value; 
       }
     }
   }


The constructor sounds like the best way to do this since it will be verified at compile tile. Of course, you could have default values for some or all of the properties and then chain constructors, so that not every property needs to be set in the constructor. Something like:

public class Person
{
    public string Name { get; set; }
    public double Height { get; set; }
    public DateTime DoB { get; set; }


    public Person(string name, double height, DateTime dob) : this(name, height)
    {
        this.DoB = dob;
    }

    public Person(string name, double height)
    {
        this.Name = name;
        this.Height = height;
        this.DoB = DateTime.Now.Date;
    }
}

This means you can construct a new Person object using either two or three parameters, but all will be set (but if you use two then DOB will get a default of today):

Person person1 = new Person("Geoff", 1.8, new DateTime(1950, 5, 12));
Person person2 = new Person("John", 1.54); // Gets default DOB


You can use an object initializer if you are using c# 3.0 onwards. This is arbitrary whether it's 'better' or not.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜