首先,我会说我已经改变了设计,不再需要它,但得到一个好的答案仍然很好
我有以下class
, ListContainer
,在我的代码中(所附代码均为 mcve ):
class ListContainer
{
public object ContainedList
{
get; private set;
}
public int Value
{
get; private set;
}
public ListContainer(object list, int value)
{
ContainedList = list;
Value = value;
}
}
还有其他一些class
在我的代码中我有一个 List<ListContainer>
我需要每个 ListContainer
包含这个List<ListContainer>
,所以我可以这样实现:
//Field in the class
List<ListContainer> mContainers = null;
//In the constructor:
mContainers = new List<ListContainer>();
mContainers.Add(new ListContainer(mContainers, SOME_CONST));
mContainers.Add(new ListContainer(mContainers, SOME_OTHER_CONST));
它工作得很好,但是当我尝试使用列表初始值设定项时:
//Field in the class
List<ListContainer> mContainers = null;
//In the constructor:
mContainers = new List<ListContainer>
{
new ListContainer(mContainers, SOME_CONST),
new ListContainer(mContainers, SOME_OTHER_CONST)
}
您希望结果是相同的,但实际上结果如下所示:
mContainers
[0] - ListContainer
ContainedList = null
Value = SOME_CONST
[1] - ListContainer
ContainedList = null
Value = SOME_OTHER_CONST
看到这个结果,我检查了此 C# 编译的输出 MSIL,并看到了以下代码:
现在,这解释了问题发生的原因,我什至查看了 CSharp 语言规范 文档,这是定义的行为:
A List can be created and initialized as follows:
var contacts = new List<Contact> { new Contact { Name = "Chris Smith", PhoneNumbers = { "206-555-0101", "425-882-8080" } }, new Contact { Name = "Bob Harris", PhoneNumbers = { "650-555-0199" } } };
which has the same effect as
var __clist = new List<Contact>(); Contact __c1 = new Contact(); __c1.Name = "Chris Smith"; __c1.PhoneNumbers.Add("206-555-0101"); __c1.PhoneNumbers.Add("425-882-8080"); __clist.Add(__c1); Contact __c2 = new Contact(); __c2.Name = "Bob Harris"; __c2.PhoneNumbers.Add("650-555-0199"); __clist.Add(__c2); var contacts = __clist;
where __clist, __c1 and __c2 are temporary variables that are otherwise invisible and inaccessible.
很明显这种行为是有意为之的。一切都在临时变量而不是原始变量上完成,是否有充分的理由?因为这对我来说似乎是一种错误的行为。
最佳答案
原因是为了避免并发线程访问要添加元素的原始变量的竞争条件。如果线程访问变量而尚未将所有元素添加到变量中,则会出现不一致。
因此,访问同一变量的两个线程将获得不一致的列表,其中包含不同的元素。
如果将元素添加到不同的行上,这不会令人震惊,但由于您使用对象初始值设定项,因此通常会将对象视为直接用其中的所有元素进行初始化,因此需要一个临时的,不可见,可变。
关于c# - 是否应该将此列表初始值设定项行为报告为 Visual Studio C# 编译器中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32921469/