1

这个答案产生,出现了一些似乎没有意义的代码:

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>();
    }
}

乍一看,人们会认为这段代码不会编译:毕竟ListOfStrings应该有一个私有的 setter,不应该以这种方式分配给它。

但是,此代码可以正常编译和运行,并且t.ListOfStrings已分配了值。

为什么这个集合初始化忽略了私有setter?

4

2 回答 2

3

在您的示例中,您实际上并没有设置属性。

C# 足够聪明,知道您正在使用 ICollection,可以使用 Add、Remove、Clear 等进行公开修改。您正在做的是相当于:

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

如果您真的尝试这样做,它将无法正常工作:

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

编辑:

由于您可能想知道如何将集合公开为只读,您可以通过将其公开为 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>();
    }
}

您也可以创建一个只读集合,但我发现这更令人困惑。如果将其公开为 IEnumerable,则该类的消费者可以枚举项目,而无法添加或删除项目。

于 2013-10-10T20:02:13.560 回答
1

为什么这个集合初始化忽略了私有setter?

它没有。这个集合初始化语法:

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

实际上是由编译器转换成这样的:

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

如您所见,ListOfStrings实际上并没有分配新值...

于 2013-10-10T20:01:50.977 回答