转载文章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