来自this answer的Spawing,出现了一些似乎没有意义的代码:
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?
答案 0 :(得分: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,那么该类的消费者可以枚举这些项目,而无法添加或删除项目。
答案 1 :(得分:1)
为什么此集合初始化会忽略私有setter?
没有。此集合初始化语法:
var t = new Testing
{
ListOfStrings =
{
"hello",
"goodbye"
}
};
实际上是由编译器转换为这样的:
var t = new Testing();
t.ListOfStrings.Add("hello");
t.ListOfStrings.Add("goodbye");
正如您所看到的,ListOfStrings
实际上并未分配新值...