简体   繁体   中英

Why collection initializer is not working together with expression body property?

I think it's best to show the code right now:

class Foo
{
    public ICollection<int> Ints1 { get; } = new List<int>();

    public ICollection<int> Ints2 => new List<int>();
}

class Program
{
    private static void Main(string[] args)
    {
        var foo = new Foo
        {
            Ints1 = { 1, 2, 3 },
            Ints2 = { 4, 5, 6 }
        };

        foreach (var i in foo.Ints1)
            Console.WriteLine(i);

        foreach (var i in foo.Ints2)
            Console.WriteLine(i);
    }
}

Obviously the Main method should print 1, 2, 3, 4, 5, 6, but it prints 1, 2, 3 only. After initialization foo.Ints2.Count is equals to zero. Why?

It's because of how you have defined the property Int2. While it is indeed a getter, it's is always returning a new list. Int1 is a read only auto property so it's always returning the same list. Equivalent compiler magic code removed for class Foo below:

class Foo
{
    private readonly ICollection<int> ints1 = new List<int>(); 
    public ICollection<int> Ints1 { get { return this.ints1; } }

    public ICollection<int> Ints2 { get { return new List<int>(); } }
}

As you can see, all mututations to Ints2 are lost because the list is always new.

Ints2 => new List<int>(); is short for Ints2 { get { return new List<int>(); } } Ints2 { get { return new List<int>(); } } . It returns a new empty list each time the property is read. You already have the fix: your first form stores the list in a field.

每次访问Ints2属性时,它都会返回新的List<int>实例。

public ICollection<int> Ints1 { get; } = new List<int>();

This line means that the backing field returned by the property is initialized with new List<int>() .

What Collection initializer do is call Add method for each element, so Ints1 will have 3 elements ( 1 , 2 , 3 ).


public ICollection<int> Ints2 => new List<int>();

Expression bodied means that you are defining the body of the getter , something like this:

public ICollection<int> Ints2 => new List<int>();
{
    get 
    {
        return new List<int>();
    }
}

Each time you call Ints2 an new instance is returned, thats why Count property returns 0 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM