Reputation: 9116
I was looking at Xamarin code base (in this case StackLayout
class) and I came with this strange line of code in C#, which I couldn't understand the syntax:
var layout = new StackLayout()
{
Children =
{ // What is this!!!?
new Label()
{
Text = "Hello",
},
new Entry()
{
Text = "Hi"
},
}
};
The code that I don't understand is the way it initializes the Children
property. Children
is a get-only property with no setter.
Not only it is being initialized, but also there is no new List<>
before {
.
Resharper can convert it to use .Add()
instead of this initialization. So it seems it is not an initialization.
I think there's something added to C# which I'm not aware of!
Upvotes: 1
Views: 80
Reputation: 5427
This is a Feature of C# 6 and the collection initializer Syntax. In short: If the Item does have an Add-Method than the Compiler will use it to initialize the Collection. See Extension Add methods in collection initializers in the C# 6 release notes.
Upvotes: 2
Reputation: 413
Not only for IList:
internal class Program
{
private static void Main(string[] args)
{
var p = new Person
{
Name = "Mark",
Address = //<<<<<<<< HERE
{
Number = 3,
Street = "Long street"
}
};
}
}
public class Person
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public int Number { get; set; }
public string Street { get; set; }
}
Btw, could somebody tell me the name of this C# feature?
Upvotes: 0
Reputation: 70671
This is just a variation of the "initializer syntax" for collections, valid when initializing property values in a new instance.
The initializer syntax in general allows assigning values to properties when using the new
operator. Then, in that context, the collection initializer syntax maps an assignment to a sequence of calls to an Add()
method (if present, which it is in this case).
This isn't unique to Xamarin. Here's a simple C# example:
public class Class1
{
public IList<string> List { get; } = new List<string>();
public static Class1 M()
{
return new Class1
{
List =
{
"foo", "bar"
}
};
}
}
Upvotes: 4
Reputation: 117084
Let's try to run your code with these classes:
public class StackLayout
{
public object[] Children;
}
public class Label
{
public string Text;
}
public class Entry
{
public string Text;
}
If I do that I get the following error:
CS1061 'object[]' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'object[]' could be found (press F4 to add a using directive or assembly reference)
If I change it to this:
public class StackLayout
{
public List<object> Children;
}
Then I get the error:
NullReferenceException: Object reference not set to an instance of an object.
So finally I do this:
public class StackLayout
{
public List<object> Children = new List<object>();
}
That works.
So the syntax you've shown is shorthand for calling an .Add(...)
method.
Upvotes: 2