读书人

C#的一个限制估计很多人都没发现过,

发布时间: 2012-02-24 16:30:38 作者: rapoo

C#的一个限制,估计很多人都没发现过
定义个结构
struct MyStruct
{
public string name;
}

然后用它
System.Collections.ArrayList myStructs = new ArrayList();
MyStruct myStruct = new MyStruct();
myStruct.name = "11111 ";
myStructs.Add(myStruct);

foreach(MyStruct my in myStructs)
{
my.name = "222 ";
}
注意了,上面
my.name = "222 ";
这行编译时会说“赋值号左边必须是变量、属性或索引器”——读可以,写不允许。写了这么久,居然今天才知道,不过想不通为什么C#要这么限制。

另,如果写成
for(int i=0; i <myStructs.Count; i++)
{
MyStruct my = (MyStruct)myStructs[i];
my.name = "333 ";
}
就没有问题

如果定义成
MyStruct[] myStructs = new MyStruct[1];
用foreach的话,也是同样的编译错误!

但是的但是:如果定义成class,就没上面的问题~~~~!

总结的说:struct搭配foreach,只读。

哪位能从机制上给解释一下.net为什么要这样做咛?

[解决办法]
这个限制和Struct的按值传递有关,个人认为可能是.NET认为这样会导致用户的误解才限制的。
[解决办法]
楼主,这个问题是你没搞明白什么是装箱什么是拆箱
[解决办法]
你放到myStructs这个里面的myStruct 原来在栈里

经过了myStructs.Add(myStruct); 现在堆里多了一个副本(这个是装箱)

foreach(MyStruct my in myStructs)这个里面的my在栈里,这里的修改怎么可能影响你在堆里的myStruct?

把内存分配看懂了就不会问这样的问题了

读书人网 >C#

热点推荐