9

Given the following example, is one objectively better/faster/safer than the other? Should object literal instantiation be a best practice where it is practical?

Where is this inappropriate?

class Person
{
    public string name;
    public int age;
}
void MakePeople()
{
    Person myPerson = new Person();
    myPerson.name = "Steve";
    myPerson.age = 21;

    Person literalPerson = new Person { name = "John", age = 22 };
}
Wesley
  • 5,381
  • 9
  • 42
  • 65
  • 3
    The generated IL from those two methods should be identical. So, no. – Phillip Schmidt Aug 15 '12 at 19:32
  • 2
    One line instead of three and clearer about intent and effect. It could be 10 times slower and it would still be a good idea. I cannot comprehend people's fixation on tiny performance differences (as a default approach; I am happy to micro-optimize hotspots). –  Aug 15 '12 at 19:33

4 Answers4

16

No, it isn't faster or slower. It is the same.

The compiler translates object initializers to a constructor call followed by setting those properties.

Person literalPerson = new Person { name = "John", age = 22 };

Turns to:

Person myPerson = new Person();
myPerson.name = "John";
myPerson.age = 22;

You should use what is more readable and what you have agreed on with your team.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 2
    +1 for using what's more readable (esp. for team environment) – JYelton Aug 15 '12 at 19:36
  • 5
    Technically it's not exactly the same since the compiler declares a temporary variable to keep the assignment to your variable atomic. – Kirk Woll Aug 15 '12 at 19:37
  • @KirkWoll Is that true even in the above case where `Person` is a reference type? – Jeppe Stig Nielsen Aug 15 '12 at 19:44
  • @Jeppe, yes, [see here](http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic13). (look at the `Point` and `Rectangle` examples and note that they are defined as a `class`) – Kirk Woll Aug 15 '12 at 19:49
  • @KirkWoll Interesting. The exact same examples are used in the C# Language Specification, so they are very credible. But how will I know that the compiler does not "optimize" this into not having any temporary variable? Wouldn't it be equivalent? The reason I ask is that more than one competent user has said on this page that the compiler will generate identical IL code in both cases. – Jeppe Stig Nielsen Aug 15 '12 at 20:17
  • 1
    @Jeppe, yes, it's a common misconception. See [this answer](http://stackoverflow.com/questions/1679780/when-using-object-initializers-why-does-the-compiler-generate-an-extra-local-va) for a full elaboration (answer #2 is from Lippert) – Kirk Woll Aug 15 '12 at 20:24
  • @KirkWoll Great link. I'm convinced. I note that Lippert says that in the specific case where it's a local variable (inside the scope of a method, and not accessible to other threads), one **could** make the optimization of not having the temporary variable, but the compiler (in its current implementation) does not optimize that. – Jeppe Stig Nielsen Aug 15 '12 at 21:03
1

Either is appropriate. It depends on what you need to do to set properties. For example, I would avoid literal instantiation in cases where some logic is needed to arrive at a property value:

Person myPerson = new Person();
myPerson.SomeProperty = if IsNewPerson ? GetPropertyFromDatabase() : GetDefaultProperty();

Edit:

One advantage to using literal object initialization in Visual Studio is that Intellisense will prompt for properties, showing only those which have not already been declared. (I've ran into code where a value was redundantly assigned when setting properties.)

JYelton
  • 35,664
  • 27
  • 132
  • 191
  • 1
    That's just personal preference though. You could still do that using literal initialization. – Servy Aug 15 '12 at 19:34
  • You could but it gets much less readable. – JYelton Aug 15 '12 at 19:34
  • And readability is a matter of preference. My point is not that this is bad, merely that the generated code is still the same, even in your example. – Servy Aug 15 '12 at 19:34
  • I would argue readability is a requirement, not a preference; at least in some workplaces. But you are correct, the IL is the same. – JYelton Aug 15 '12 at 19:35
  • 1
    I didn't say having your code readable is a preference, I'm saying what is more readable is a preference. Some people find certain code snippets easy to read and others find it hard. Also note that it's common to add linebreaks/whitespace to object initializes when you have either complex assignments, or many properties, at which point all you're really removing is the redundant variable name over and over. That is the pattern I frequently follow. – Servy Aug 15 '12 at 19:38
0

If you take a look at the IL that is generated, I'm pretty sure you'll find that they are identical. Using object initializers is just a compiler shortcut.

CodingGorilla
  • 19,612
  • 4
  • 45
  • 65
0

I don't think speed should be what drives this decision. There is probably very little difference between the speed of either method.

I think code readability should be the prime factor in which way you go. Using that criteria, I think they are very close and it comes down to personal preference or whatever your team decides on. However, I think in the case of a object with requires many properties to be set, explicitly calling setters is a little more readable.

Aheho
  • 12,622
  • 13
  • 54
  • 83