要修改自定义结构的值,应该用Class而不是Struct

转载文章http://blog.csdn.net/onlyou930/article/details/5568319

 

编译错误 CS1612 
Cannot modify the return value of ‘expression‘because it is not a variable
 
无法修改“expression”的返回值,因为它不是变量 
出现这种错误的最常见情况是: 
AnObject.AnStruct.Vaule = xxx; 
考虑如下程序:初看没什么问题,实际上根本无法编译 
usingSystem; 
usingSystem.Collections.Generic; 
usingSystem.Text; 
namespaceConsoleApplication1 
{ 
publicstruct Rectangle 
{ 
privateint _Width; 
privateint _Height; 
publicint Width 
{ 
get{ return _Width; } 
set{ _Width = value; } 
} 
publicint Height 
{ 
get{ return _Height; } 
set{ _Height = value; } 
} 
publicRectangle(int width, int height) 
{ 
this._Width= width; 
this._Height= height; 
} 
} 
publicclass Draw 
{ 
privateRectangle _rect = new Rectangle(0, 0); 
publicRectangle MyRect 
{ 
get{ return _rect; } 
set{ _rect = value; } 
} 
publicDraw() { } 
publicDraw(int mapWidth, int mapHeight) 
{ 
_rect= new Rectangle(mapWidth, mapHeight); 
} 
} 
classProgram 
{ 
staticvoid Main(string[] args) 
{ 
Drawdraw = new Draw(); 
draw.MyRect.Width= 20;//《==编译错误 
draw.MyRect.Height= 12;《==编译错误 
} 
} 
} 
draw是引用类型,MyRect是struct,也就是值类型,draw.MyRect会调用 
publicRectangle MyRect 
{ 
get{ return _rect; } 
} 
而值类型默认是按值传递的,返回的是栈上_rect的一份临时的、本地的拷贝,我们暂且称之为temp_rect, 
draw.MyRect.Width= 20 等同于temp_rect.Width = 20; 
因此即使能对它进行修改也无法反映到draw.MyRect本身(即_rect)的,即这是一个毫无何意义的操作,因此编译器就从源头上禁止了这样的操作。 
解决方法: 
1)把struct替换成class,这样,MyRect就成了一个对象(引用类型),draw.MyRect就会返回_rect在堆上的实际地址,修改也会反映到实际的对象 
2)如果非要用struct不可的话,需要设置一个中间变量: 
Drawdraw = new Draw(); 
RectangletempRect = new Rectangle(); 
tempRect.Width= 20; 
tempRect.Height= 12; 
draw.MyRect= tempRect; 
这样实际上是替换draw对象的整个_rect属性。 
参考: 
MSDN: Compiler ErrorCS1612 编译器错误 CS1612(C#)  
看一下就知道了,中文的比英文原版的逊多了 
C# - Struct in aclass.. can not access properties of thestruct 
延伸阅读: 
CLR GenericsLimitation - Modifying Values In Situ In aContainer
 
C#: List ofstruct

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章