These are basically a syntactic shorthand for constructing and initialising an object or collection in one statement.
Consider the example where a class has only a default constructor but you need to set certain properties before you can use it as you wish. The C# 2.0 and 3.0 versions of the code that you would write are:
C# 2.0
MultProps props2 = new MultProps();
props2.Name = “Fred”;
props2.Value = 1; |
C# 3.0
| MultProps props32 = new MultProps { Name = “Blogs”, Value = 2 }; |
As you can see from this simple example, construction and initialisation can now be performed on a single line. It’s worth noting that the normal empty bracket syntax may also be used but this is not needed, which means that object initialisers can also be used with constructors that require input parameters:
| MultProps props32 = new MultProps() { Name = “Blogs”, Value = 2 }; |
The above are examples of object initilisers.
Collection initialisers follow the same concept but apply to all new instances of classes that implement the IEnumerable interface. This means that collection initialisers will work on all collections from loosely typed Arrays to a strongly typed List<> objects right through to your own home-grown collections:
C# 3.0 More Object Initialisers & Some Collection Initialisers
// No constructor used, 2 properties
City nottingham = new City { Name = “Nottingham”, Celsius = 15 };
// Constructor used + 1 property
City sheffield = new City(”Steel production”) { Name = “Sheffield” };
// Default constructor + 1 property
City derby = new City() { Celsius = -6.2 };
// Object initialisers
// Strongly typed
List<City> cities = new List<City> { nottingham, sheffield, derby };
// Two-dimensional array
City[][] cityGroups = new City[][]
{
new City[]{nottingham, sheffield, derby},
// Includes a null entry
new City[]{new City(){Name = “London”}, null}
}; |
Object and collection initialisers can be used in the following situations:
- With any accessible fields or properties - so public/internal variables (spit) in addition to public/internal properties.
- With named types.
- With anonymous types. This is actually the only way that an anonymous type can be initialised.
NOTE: There’s a little strangeness going on. The MSDN documentation states that “It is a compile-time error to use a collection initializer with a nullable struct”. So why does the following work (compile and run)?
internal void NullableTest()
{
StructCity? nullAbleA = new StructCity { Name = “Won’t work” };
List<StructCity?> nullableList = new List<StructCity?> { null };
foreach (StructCity? a in nullableList)
{
Console.WriteLine(a.HasValue);
}
} |
In the example above I am clearly using both object initialisation and collection initialisation on a nullable struct but I get NO compile error and I can enumerate all the elements later. Am I missing something?
Oh well, I seam never to use structs anyway.
More details can be found here.
To read about more C# 3.0 enhancements click here.