10

I have just learned about object initializers and was wondering what the best practices for when to use them are.

This is what I read about them: http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx It makes it clear that they are necessary for creating anonymous types but I would like to know if I should try to prefer them to normal constructors in all the other cases.

Sarien
  • 6,647
  • 6
  • 35
  • 55
  • http://stackoverflow.com/questions/740658/whats-the-difference-between-an-object-initializer-and-a-constructor – dugas Mar 21 '13 at 18:31
  • 5
    This can be somewhat subjective. Got an immutable type? An object that needs to encapsulate state? An object the declares injectable dependencies? Prefer a constructor. Got a simple (yet mutable) DTO? Feel free to use initializer syntax. Use the tool that makes sense for what you are trying to accomplish. – Anthony Pegram Mar 21 '13 at 18:33
  • Even in a simple DTO, I'd still use constructor arguments for anything *required* for the class. – Reed Copsey Mar 21 '13 at 18:39

4 Answers4

28

I would like to know if I should try to prefer them to normal constructors in all the other cases.

I would say no.

Constructors have a huge number of advantages. Using a constructor, the compiler will enforce that all required data is provided to your type. This means you can make it impossible to create an instance of your type that is in an invalid state, which allows you to proactively prevent many bugs.

Object initializers, on the other hand, create many disadvantages. You must provide publically settable properties for any data you need to initialize. They are not required at construction time, so users of your type can accidentally leave out some data.

In general, anything required for your class to function should be required in the constructor. Object initializers can still be used, even if you have a custom constructor, but should only be used for data that's optional in setting on your class. Mixing both in an initialization is fine, which means you can do:

var yourInst = new YourClass(req1, req2) { OptionalProperty = opt1 }

This can help reduce the number of constructor overloads required (similar to using optional arguments, but without some of the disadvantages of versioning in optional arguments).

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • In addition, if your reason for using object initialisers is readability then consider named parameters in your constructors instead - https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments. – ethane Apr 16 '18 at 07:25
10

I believe you are confusing things.

Object initializers will call the default (or a specified) constructor of the class! So you can't really use object initializers instead of the normal constructor. So when using an object initializer you are calling the constructor anyway.

If you are wondering about Object Initializers for a class that you are designing, than the answer still applies. Make sure to provide the necessary constructors that make sense. You don't need to do anything special to enable/allow object initializers. They are syntactic sugar provided by the C# compiler since version 3.0 and allow users of your class to initialize public members of your class, immediately after construction.

Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
6

A good rule of thumb is:

  • If it's required to make the class work right, it should be a constructor parameter
  • If changing it would break the class, it should be a constructor parameter
  • If it's optional, has a sane default, and/or simply and safely changes how the class behaves, it should be an initializer.

The main advantage to initializers is that you don't have to set them when the object is created - you can set them later, based on other logic.

Bobson
  • 13,498
  • 5
  • 55
  • 80
1

I currently see the following problems with using them:

  1. The properties that are assigned have to be changeable. This seems undesirable because if the data is passed to a constructor I can check it there and make object creation fail if the data provided is insufficient or wrong. If data can be assigned with a property I suddenly have to figure out what the state of my object is, whether everything is properly created yet or which other state I might be in.
  2. The properties that are assigned have to be public. This means that access to things that might otherwise be private will have to be exposed and then later restricted by using an interface or something like that.

So my working theory is: Don't use object initializers they encourage stupid things.

Sarien
  • 6,647
  • 6
  • 35
  • 55
  • I agree with this EXCEPT if you are using a builder class purely to initialise a private constructor of an immutable class. Then it's perfectly ok. And it's ok for things with narrow scope, of course. – Matthew Watson Mar 21 '13 at 18:33
  • The only way to fail object creation is to throw an exception. – Bobson Mar 21 '13 at 18:34
  • 1
    As Miky stated, you are confusing things. Object initializers should only be used to make cleaner code. You still write the same underlying code, it is just how it is used. See Reed's answer in the link made by @dugas – Justin Pihony Mar 21 '13 at 18:34
  • @Bobson: What he means is that if you use properties to initialise the object, it must be possible to create it without setting that/those properties. – Matthew Watson Mar 21 '13 at 18:35
  • This doesn't make sense to me - why have writeable properties if changing them causes the class construction to fail? What would happen if set after construction? – Ani Nov 07 '22 at 16:10