Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why bother with initializers? (.net)

I have this:

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;

But I could have this:

AudioPlayer player = new AudioPlayer
{
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

If I convert to 'new way of writing things', what do I gain besides unreadability? Will it make me closer to lambda functions ( => ) ?

Does it have something to do with RAII?

ADDITION:

Some answered that normal initialization could left the object in 'invalid' state after for example setting only a Directory property - my observation here is that is someone who was designing the object probably designed it in a way that only values that MUST be really entered are entered through real constructor, and all other could be freely modified later.

like image 500
Daniel Mošmondor Avatar asked Oct 03 '10 13:10

Daniel Mošmondor


3 Answers

With such a simple example, you indeed do not gain much. However, it gets different, when you have this:

var player = new AudioPlayer
{
    Car = new Car()
    {
        WheelSize = new Inch(21),
        Driver = new Person()
        {
            Age = 53,
            Type = LicenseType.B,
            Family =
            {
                new Person("Jane"),
                new Person("Pieter"),
                new Person("Anny")
            }
        }
    }
    Directory = vc.Directory,
    StartTime = vc.StarTime,
    EndTime = vc.EndTime
};

Try doing this with the old way. It gets really ugly.

like image 134
Steven Avatar answered Nov 19 '22 21:11

Steven


Consider you want to pass your newly created object to some method (and not do anything else with it). You can either write it the old way:

AudioPlayer player = new AudioPlayer();
player.Directory = vc.Directory;
player.StartTime = vc.StarTime;
player.EndTime = vc.EndTime;
some.Method(player);

Or you can use object initializers:

some.Method(
  new AudioPlayer
  {
      Directory = vc.Directory,
      StartTime = vc.StarTime,
      EndTime = vc.EndTime
  });

Using object initilizers, you can clearly see what the code does and that the object is not used later.

Also, I think the readability (and “writability”) is better: you don't have to repeat the variable name endlessly.

like image 2
svick Avatar answered Nov 19 '22 23:11

svick


You don't just gain unreadability, you also gain a greater ability to cause bugs by putting objects into an invalid state.

The only thing it has to do with RAII is that RAII depends on sensible invariants, and initialisers make it easy to break invariants.

However, it can be very useful in creating an anonymous value, or in creating plain-old-data style objects (where the class is a "dumb" container of values and invariants aren't as important). These can be particularly useful with lambda functions and linq expressions, though are neither absolutely necessary for them, nor restricted to them.

When a class maintains an invariant, then it is not a good idea to initialise it in such a way, and as a rule any rewrite from a constructor that takes values to the new syntax is a bad idea.

In your example your first case doesn't use its constructor to initialise to a guaranteed valid state. That's a bad smell, (what is a player meant to do before it has a directory, start time and end time?) but when it's reasonable for a given class, then so is use of the new syntax.

That the new syntax can set up the object in a single expression, which can in turn be part of another expression, is where this could be useful, and yes that does include in lambda expressions.

like image 2
Jon Hanna Avatar answered Nov 19 '22 21:11

Jon Hanna