Yippie-Ki-Yay
Yippie-Ki-Yay

Reputation: 22794

C# constructors

Could someone advice me on what approach to take when writing C# constructors?

In other languages, like C++, everything is fine - you usually don't make the internal fields visible and provide getters / setters for them.

This means, you could provide your class with constructors, which initialize all / some of your local members and be happy.


C#, however, has properties, which allows us to write something like:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }

This allows chaining for the object construction and, as I assume, can remove a lot of constructors, which would be required if we didn't have properties.

Combining this with default values for properties, as I assume, we can completely get rid of non-specialized constructors, which actually do some work.

Now - is it okay to remove redundant constructors and allow object constructing via field initializing?

What are the drawbacks of this approach? Could someone give general recommendations about combining the usage of fields and constructors, some rules of thumb, probably?

Thank you.

Upvotes: 12

Views: 1120

Answers (9)

ZombieSheep
ZombieSheep

Reputation: 29953

In my opinion, there is nothing wrong with having what you term as redundant constructors. If it makes enough sense for you to want to define a constructor, it is probably because there's a genuine need to do it that way.

Upvotes: 6

Matthew Nichols
Matthew Nichols

Reputation: 5035

I suspect you are referring to domain objects here, but in the case of services, injecting the dependencies of the service in through a constructor makes the service more self documenting, as opposed to "newing up" your dependencies. Additionally this sets you up to use dependency injection containers more easily.

Upvotes: 0

SWeko
SWeko

Reputation: 30872

The object initializer syntax is just a syntactic sugar. Even in C# 1 you could write

Class c = new Class();
c.Property1 = value1;
c.Property2 = value2;
c.Property3 = value3;
....

C# 3 basically shortens the syntax to:

Class c = new Class 
{
   Property1 = value1, 
   Property2 = value2, 
   Property3 = value3
   ....
}

The point od the counstructor is not to just set the fields, the constructor should logically construct the object, based on the parameters, so that when the constructor returns, what you get is an object that is ready to be used.

Upvotes: 1

Steve
Steve

Reputation: 8511

Is it OK? Well, that depends...

In order to use object initialisers you will need to expose public setters to all your fields, you may not want this. If you are happy to expose them then I'd say go ahead and remove constructors. However just because you can do someting does not mean you should. I would say removing the constructors should be something you do if you find all your fields are publicly settable, do not make the fields settable just to allow you to remove the constructor.

Upvotes: 0

Adam Houldsworth
Adam Houldsworth

Reputation: 64467

The approach of public parameterless construction followed by property initialization is popular (required?) for use in XAML, a lot of WPF toys do this.

The only problem you face is a partially initialized object, but then you can simply validate object state prior to attempting to use the fields.

Personally, I make critical values parameters in the constructor, I make copy constructors out of a copy of the object and a range of optional parameters, and I've yet to make something that needs consuming by XAML.

Upvotes: 1

Phil Sandler
Phil Sandler

Reputation: 28016

The code you posted is using what are called Object Initializers, which are really just syntactic sugar that were introduced fairly recently. Using object initializers are just a shorthand way of calling a constructor and setting properties. You should continue to use constructors in C# the same way that you have used them in other languages--the general rule is that if a class requires an object or value for it to be initialized properly, that parameter should be passed through the constructor. If the value isn't required, it is reasonable to make it a settable property.

Generally speaking, I avoid using setters at all when possible (there are many, many cases when it's not possible).

Upvotes: 2

Mitch Wheat
Mitch Wheat

Reputation: 300489

Best practice is to create an object in a usable state; try to limit reliance on property setters.

It reduces the chances that you create an object which is incomplete and leads to less fragile code.

Upvotes: 2

Tergiver
Tergiver

Reputation: 14507

My own rule of thumb is simple: If something is required to completely construct the object, it should be a ctor parameter.

A good example is one of the Stream helper objects like StreamReader or BinaryReader. They cannot function without an associated Stream object, so that must be specified in the constructor.

Upvotes: 16

RB.
RB.

Reputation: 37172

Constructors can be used to force the consumer to supply values to the class.

My rule of thumb is that Fields are for optional data, while constructors can be used to force required data.

The question is something of a false dichotomy though. C++ behaves the same way as C# - "Fields" (which are actually properties - fields are class-level variables) are generally used as getters/setters for setting internal values, and the new syntax which allows you to set fields is just a shorthand for

Class x = new Class();
x.Field1 = new Field1();
x.Field2 = new Field2();

Upvotes: 4

Related Questions