C #: assign data to properties through constructor versus instantiation

Suppose I have an Album class:

 public class Album { public string Name {get; set;} public string Artist {get; set;} public int Year {get; set;} public Album() { } public Album(string name, string artist, int year) { this.Name = name; this.Artist = artist; this.Year = year; } } 

When I want to assign data to an object of type Album , what is the difference between the following two approaches:

Through the constructor

 var albumData = new Album("Albumius", "Artistus", 2013); 

or when creating an instance

 var albumData = new Album { Name = "Albumius", Artist = "Artistus", Year = 2013 }; 
+49
c #
Oct 02 '13 at
source share
3 answers

Both approaches call the constructor, they just call different. This code:

 var albumData = new Album { Name = "Albumius", Artist = "Artistus", Year = 2013 }; 

is a syntax shorthand for this equivalent code:

 var albumData = new Album(); albumData.Name = "Albumius"; albumData.Artist = "Artistus"; albumData.Year = 2013; 

The two are identical after compilation. Therefore, if the constructor without parameters was not publicly available:

 public Album() { } 

then you canโ€™t use the object initializer at all. Thus, the main question is not what to use when initializing the object, but what constructor it provides in the first place. If an object provides two constructors (for example, the one in your example), then we can assume that both paths are equally valid for constructing the object.

Sometimes objects are not exposed by dimensionless constructors, because they require certain values โ€‹โ€‹for construction. Although in such cases, you can still use the initializer syntax for other values. For example, suppose you have these constructors on your object:

 private Album() { } public Album(string name) { this.Name = name; } 

Since a constructor without parameters is private, you cannot use it. But you can use a different one and still use the initializer syntax:

 var albumData = new Album("Albumius") { Artist = "Artistus", Year = 2013 }; 

The result after compilation will then be identical:

 var albumData = new Album("Albumius"); albumData.Artist = "Artistus"; albumData.Year = 2013; 
+79
02 Oct '13 at 13:45
source share

Object initializers are awesome because they allow you to create an inline class. The trade-off is that your class cannot be immutable. Consider:

 public class Album { // Note that we make the setter 'private' public string Name { get; private set; } public string Artist { get; private set; } public int Year { get; private set; } public Album(string name, string artist, int year) { this.Name = name; this.Artist = artist; this.Year = year; } } 

If a class is defined this way, it means that there really is no easy way to change the contents of a class after it is created. Invariability has advantages. When something is immutable, it is much easier to determine that it is correct. After all, if it cannot be modified after construction, then there is no way that it will ever be โ€œwrongโ€ (after you determine the correctness of its structure). When you create anonymous classes, for example:

 new { Name = "Some Name", Artist = "Some Artist", Year = 1994 }; 

the compiler will automatically create an immutable class (i.e. anonymous classes cannot be changed after construction), because immutability is so useful. Most C ++ / Java style guides often encourage the creation of const (C ++) or final (Java) members for exactly this reason. Large applications are much easier to check when the number of moving parts is less.

With everything said, there are situations when you want to quickly change the structure of your class. Let's say I have a tool that I want to customize:

 public void Configure(ConfigurationSetup setup); 

and I have a class that has several elements, such as:

 class ConfigurationSetup { public String Name { get; set; } public String Location { get; set; } public Int32 Size { get; set; } public DateTime Time { get; set; } // ... and some other configuration stuff... } 

Using object initializer syntax is useful when I want to configure some combination of properties, but not all at once. For example, if I just want to configure Name and Location , I can simply do:

 ConfigurationSetup setup = new ConfigurationSetup { Name = "Some Name", Location = "San Jose" }; 

and this allows me to create some combination without having to define a new constructor for every possible permutation.

In general, I would say that turning your classes into a fixed state in the long run will save you a lot of development time, but with the object initializer syntax it will greatly simplify the configuration of certain configuration permutations.

+16
Oct 02 '13 at 13:45
source share

The second approach is the object initializer in C #

Object initializers allow you to assign values โ€‹โ€‹to any available fields or object properties during creation without the need to explicitly call the constructor .

First approach

 var albumData = new Album("Albumius", "Artistus", 2013); 

explicitly calls the constructor, whereas in the second call, the constructor of the method is implicit. With an object initializer, you can also leave some properties. How:

  var albumData = new Album { Name = "Albumius", }; 

The object initializer translates into something like:

 var albumData; var temp = new Album(); temp.Name = "Albumius"; temp.Artist = "Artistus"; temp.Year = 2013; albumData = temp; 

Why it uses a temporary object (in debug mode) is answered here by Jon Skeet.

As for the advantages of both approaches, IMO, the object initializer will be easier to use on purpose if you do not want to initialize all the fields. As for the performance difference, I donโ€™t think it will happen, since the object initializer calls the constructor with a lower value and then assigns the properties. Even if there is a difference in performance, it should be negligible.

+9
Oct 02 '13 at
source share



All Articles