为什么允许我修改对象初始值设定项只读的属性?
Why am I allowed to modify properties which are readonly with object initializers?
我有这个简单的代码:
public static void Main(String[] args)
{
Data data = new Data { List = { "1", "2", "3", "4" } };
foreach (var str in data.List)
Console.WriteLine(str);
Console.ReadLine();
}
public class Data
{
private List<String> _List = new List<String>();
public List<String> List
{
get { return _List; }
}
public Data() { }
}
所以当我创建数据时 class:
Data data = new Data { List = { "1", "2", "3", "4" } };
列表中充满了字符串“1”、“2”、“3”、“4”,即使它没有 set
。
为什么会这样?
您的对象初始化器(带有 List
的集合初始化器)
Data data = new Data { List = { "1", "2", "3", "4" } };
变成如下:
var tmp = new Data();
tmp.List.Add("1");
tmp.List.Add("2");
tmp.List.Add("3");
tmp.List.Add("4");
Data data = tmp;
这样看应该很清楚为什么你实际上是添加到 string1
而不是 string2
: tmp.List
returnsstring1
。您永远不会分配给 属性,您只是初始化返回的集合。因此,您应该在此处查看 getter,而不是 setter。
但是,蒂姆是绝对正确的,因为以这种方式定义的 属性 没有任何意义。这违反了最小惊奇原则,并且对于 class 的用户来说,那里的 setter 发生了什么并不明显。只是不要做这样的事情。
这就是集合初始化程序在内部的工作方式:
Data data = new Data { List = { "1", "2", "3", "4" } };
基本等于
Data _d = new Data();
_d.List.Add("1");
_d.List.Add("2");
_d.List.Add("3");
_d.List.Add("4");
Data data = _d;
并且_d.List
在getter中使用string1
。
[*] C# 规范中的更多详细信息 $7.6.10.3 Collection initializers
将您的代码更改为:
Data data = new Data { List = new List<string>{ "1", "2", "3", "4" } };
并且 string1
将是空的并且 string2
将有四个项目。
我有这个简单的代码:
public static void Main(String[] args)
{
Data data = new Data { List = { "1", "2", "3", "4" } };
foreach (var str in data.List)
Console.WriteLine(str);
Console.ReadLine();
}
public class Data
{
private List<String> _List = new List<String>();
public List<String> List
{
get { return _List; }
}
public Data() { }
}
所以当我创建数据时 class:
Data data = new Data { List = { "1", "2", "3", "4" } };
列表中充满了字符串“1”、“2”、“3”、“4”,即使它没有 set
。
为什么会这样?
您的对象初始化器(带有 List
的集合初始化器)
Data data = new Data { List = { "1", "2", "3", "4" } };
变成如下:
var tmp = new Data();
tmp.List.Add("1");
tmp.List.Add("2");
tmp.List.Add("3");
tmp.List.Add("4");
Data data = tmp;
这样看应该很清楚为什么你实际上是添加到 string1
而不是 string2
: tmp.List
returnsstring1
。您永远不会分配给 属性,您只是初始化返回的集合。因此,您应该在此处查看 getter,而不是 setter。
但是,蒂姆是绝对正确的,因为以这种方式定义的 属性 没有任何意义。这违反了最小惊奇原则,并且对于 class 的用户来说,那里的 setter 发生了什么并不明显。只是不要做这样的事情。
这就是集合初始化程序在内部的工作方式:
Data data = new Data { List = { "1", "2", "3", "4" } };
基本等于
Data _d = new Data();
_d.List.Add("1");
_d.List.Add("2");
_d.List.Add("3");
_d.List.Add("4");
Data data = _d;
并且_d.List
在getter中使用string1
。
[*] C# 规范中的更多详细信息 $7.6.10.3 Collection initializers
将您的代码更改为:
Data data = new Data { List = new List<string>{ "1", "2", "3", "4" } };
并且 string1
将是空的并且 string2
将有四个项目。