mehrandvd
mehrandvd

Reputation: 9116

What is this strange way of initializing IList<T> in Xamarin code base?

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

Answers (4)

Noffls
Noffls

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

Ha Pham
Ha Pham

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

Peter Duniho
Peter Duniho

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

Enigmativity
Enigmativity

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

Related Questions