Pregunta

Spawing from this answer, some code appeared that seems to not make sense:

class Program
{
    static void Main(string[] args)
    {
        var t = new Testing
        {
            ListOfStrings =
            { 
                "hello", 
                "goodbye" 
            }
        };

        Console.ReadKey();
    }
}

public class Testing
{
    public List<string> ListOfStrings { get; private set; }

    public Testing()
    {
        ListOfStrings = new List<string>();
    }
}

At first glance one would think this code wouldn't compile: after all ListOfStrings is supposed to have a private setter, and shouldn't be able to be assigned to in this manner.

However, this code compiles and runs fine, and t.ListOfStrings has the values assigned.

Why does this collection initialization ignore the private setter?

¿Fue útil?

Solución

In your example you are not actually setting the property.

C# is smart enough to know that you are using an ICollection which can be publicly modified using Add, Remove, Clear, etc. What you are doing is the equivalent of this:

t.AddRange(new string[] { "hello", "goodbye" });

If you actually tried to do this it would not work:

var t = new Testing
{
    ListOfStrings = new List<string>(),
};

EDIT:

Since you might be wondering how to expose a collection as readonly, you can do this by just exposing it as an IEnumerable:

public class Testing
{
    private List<string> _listOfStrings;
    public IEnumerable<string> MyStrings
    {
        get
        {
            foreach (var s in _myStrings)
                yield return s;
        }
    }

    public Testing()
    {
        _listOfStrings = new List<string>();
    }
}

You could also create a readonly collection but I find that is more confusing. If you expose it as IEnumerable then consumers of the class can enumerate through the items with no ability to add or remove items.

Otros consejos

Why does this collection initialization ignore the private setter?

It doesn't. This collection initialization syntax :

    var t = new Testing
    {
        ListOfStrings =
        { 
            "hello", 
            "goodbye" 
        }
    };

is actually transformed by the compiler to something like this:

var t = new Testing();
t.ListOfStrings.Add("hello");
t.ListOfStrings.Add("goodbye");

So as you can see, ListOfStrings isn't actually assigned a new value...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top