views:

194

answers:

6

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.

+1  A: 

I believe this syntax has been added because it is easier to use with lambda expression, so you can do something like item => new Person() { Name = item.Name } easily.

I don't think it has anything to do with RAII though..

tia
+8  A: 

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.

Steven
+1. A trivial point, but the parantheses are not required when calling the parameterless constructor.
Ani
@Ani: That's why `new AudioPlayer` has no parantheses :-)
Steven
+2  A: 

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.

svick
Well, here comes the 'with' keyword from VB6! :)
Daniel Mošmondor
+1  A: 

You gain 21 characters less code. And less code means less errors. And to gain even more you could use implicit variable type inference: var player = new AudioPlayer {

Darin Dimitrov
+2  A: 

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.

Jon Hanna
+2  A: 

Initializers become required, and not just useful, when dealing with anonymous types.

e.g.:

var x = new { Foo = "foo", Bar = "bar" };

Richard Hein
This particular instance, is it compatible with .net 2.0? I.e. is it a feature of a IDE, compiler, or .net runtime?
Daniel Mošmondor