Click here to Skip to main content
Click here to Skip to main content

Two things that only Initializers can easily do

, 21 Feb 2012
Rate this:
Please Sign up or sign in to vote.
There are two things I’ve found that can’t be done easily without object initializers.

Refresher on Initializers

For those of you who don’t know or can’t remember, object initializers are when you assign members of a class or struct immediately after construction in the initializer syntax. For example, assuming we had a Point struct with typical X and Y members:

// first constructs Point using default constructor, then assigns X & Y
var p1 = new Point() { X = 3, Y = 10 };
 
// this is logically equivalent to:
var p2 = new Point();
p2.X = 3;
p2.Y = 10;

And collection initializers are when you assign the contents of an IEnumerable that contains an Add() method at construction:

// can do with primitives
var listOfInt = new List<int>() { 1, 2, 3, 4, 5 };
 
// or combine with object initialization to do complex:
var listOfPoint = new List<Point>() 
    {
        new Point() { X = 1, Y = 2 },
        new Point() { X = 5, Y = 7 },
        new Point() { X = 0, Y = 0 }
   };

Now, whether you put the curlies on the same line or next line is purely a matter of style and taste for initializers. Object initializers work for any public mutable properties or fields of a class, and collection initializers work for any collection that implements IEnumerable and has an Add() method. So it’s really easy to enable both types of initializers for any types you create as necessary.

So that’s the initializers in a quick refresher nutshell, I didn’t want to delve into too much usage detail as that’s beyond the scope of this particular post. There’s plenty of good nutshell posts, I also cover them briefly in the second of my Five Little Wonders posts here.

The Difference?

Now, many of you may be looking at this and thinking, “yeah, big deal, it’s a syntactical shortcut and no more or no less”. Well, you’re partly right. There are two things I’ve found that can’t be done easily without object initializers. I’m not claiming that they are necessarily impossible, but I can see no way to do it as easily or as cleanly.

So what are these two things?

  1. Constructing and initializing an anonymous argument to a method.
  2. Initializing a static member and still maintaining BeforeFieldInit CIL attribute.

Constructing and Initializing an Anonymous Argument

No, I’m not talking about anonymous types here, but an anonymous argument. That is, being able to construct an argument in the call to a method or property without specifying a variable name.

For example, let’s say we have our mythical Point class and want to construct a new pair of Points to draw a line, we could do something like this:

var first = new Point();
first.X = 3;
first.Y = 7;
 
var second = new Point();
second.X = 9;
second.Y = 13;
 
DrawLine(first, second);

Obviously, that’s a lot of lines of code for some throw-away points. But now, with initializers, we can easily do:

DrawLine(new Point() { X = 3, Y = 7}, new Point() { X = 9, Y = 13});

Now this is a contrived example, to be sure, but notice that we’re constructing an anonymous object and immediately assigning the elements in the call to the method. This is something you can’t do well without initializers. Now, to be fair, you could create a constructor that takes the coordinates, but what if you have no control over the class or need to set a property that is not available in the constructor? Before initializers you were out of luck.

I find this extremely handy with collection intializers. For example, I have a JMS messaging abstraction library that hides the underlying JMS implementation from my business layer so I can swap out providers as needed. In that library I define a Message that is a generic abstraction of a JMS message. Besides obviously having a Text property, it has a List<messageproperties>.

Because of collection initializers, I can easily create a JMS message at the point of sending it and assign the properties using the collection initializer:

public void SendHeartbeat()
{
    _jmsSender.Send(new Message("HEARTBEAT")
        {
            { "MACHINE", Environment.MachineName },
            { "TIME", DateTime.Now }
        });
}

Yes, I could have created the object above and then passed the variable into the method call. But there’s really no need since it’s only used once. Without initializers, you can’t anonymously create an argument and initialize it in the call itself. Now, it may boil down to the same CIL in the end, but in terms of C# code (and VB.NET too) it can really reduce the amount of clutter.

Initializing a Static Member While Preserving BeforeFieldInit

The BeforeFieldInit CIL attribute is applied to most classes or structs that do not have a static constructor. For those who don’t know, a static constructor is a constructor in a class orstruct that has no access modifier, takes no parameters, and has the keyword static in front of it.

For example, it used to be that if you had a class with a static collection member, you would have to initialize it in a static constructor like so:

public class NotBeforeFieldInit
{
    public static List<int> ThisList = new List<int>();
     
    static NotBeforeFieldInit()
    {
        ThisList.Add(1);
        ThisList.Add(2);
        ThisList.Add(3);
        ThisList.Add(4);
        ThisList.Add(5);
   }
}

Now, this looks very innocent, but it turns out whenever you have an explicit static constructor, the C# compiler will not mark the type with the BeforeFieldInit CIL property.

.class public auto ansi NotBeforeFieldInit
       extends [mscorlib]System.Object
{
} // end of class NotBeforeFieldInit 

So why is this important? Well, the BeforeFieldInit property controls how the static fields are initialized. If the property is present, it means that the property can be initialized any time before it’s first call. However, if a class has an explicit static constructor, it can’t mark the type with this property because it has to first check and make sure that the static constructor has been run before any static field on the type can be accessed. This means a very slight degradation in performance, as any attempt to access a static field has to do a check to make sure the static constructor has already been called.

So how does an initializer help you here? Oddly enough, it allows you to construct and initialize the object and still preserve the BeforeFieldInit property of your class, which means better performance as it won’t have to check each call for a static constructor call:

public class BeforeFieldInit
{
    public static List<int> ThisList = new List<int>() { 1, 2, 3, 4, 5 };
}

Now, using the initializer, we can look at the generated IL:

.class public auto ansi beforefieldinit BeforeFieldInit
       extends [mscorlib]System.Object
{
} // end of class BeforeFieldInit

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Aniket Yadav
Software Developer IIS
India India
I am a Embedded as well as Software developer from Pune.

Comments and Discussions

 
GeneralReason for my vote of 5 Very Nice PinmemberSnehalShinge24-Feb-12 23:59 
GeneralDoesn't initializing the field with a call to a static metho... PinmvpPaulo Zemek23-Feb-12 9:18 
GeneralReason for my vote of 5 nice tip, I didn't know about static... Pinmemberjohannesnestler21-Feb-12 23:41 
GeneralRe: It was my pleasure. Thanks for you comment Pinmemberaniketyadav721-Feb-12 23:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 21 Feb 2012
Article Copyright 2012 by Aniket Yadav
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid