C# struct的陷阱:无法修改“...”的返回值,因为它不是变量

5 篇文章 0 订阅

无法修改“System.Nullable<xmlread.Program.NewYorkTime>.Value”的返回值,因为它不是变量

编译错误 CS1612 

Cannot modify the return value of ‘expression‘ because it is not a variable  
无法修改“expression”的返回值,因为它不是变量 
出现这种错误的最常见情况是: 
AnObject.AnStruct.Vaule = xxx; 
考虑如下程序:初看没什么问题,实际上根本无法编译 

using System;  
using System.Collections.Generic;  
using System.Text;  
namespace ConsoleApplication1  
{  
public struct Rectangle  
{  
private int _Width;  
private int _Height;  
public int Width  
{  
get { return _Width; }  
set { _Width = value; }  
}  
public int Height  
{  
get { return _Height; }  
set { _Height = value; }  
}  
public Rectangle(int width, int height)  
{  
this._Width = width;  
this._Height = height;  
}  
}  
public class Draw  
{  
private Rectangle _rect = new Rectangle(0, 0);  
public Rectangle MyRect  
{  
get { return _rect; }  
set { _rect = value; }  
}  
public Draw() { }  
public Draw(int mapWidth, int mapHeight)  
{  
_rect = new Rectangle(mapWidth, mapHeight);  
}  
}  
class Program  
{  
static void Main(string[] args)  
{  
Draw draw = new Draw();  
draw.MyRect.Width = 20;//《== 编译错误  
draw.MyRect.Height = 12;《== 编译错误  
}  
}  
}  
draw是引用类型,MyRect是struct,也就是值类型,draw.MyRect会调用  
public Rectangle 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不可的话,需要设置一个中间变量  
Draw draw = new Draw();  
Rectangle tempRect = new Rectangle();  
tempRect.Width = 20;  
tempRect.Height = 12;  
draw.MyRect = tempRect;  
这样实际上是替换draw对象的整个_rect属性。  
参考:  
MSDN: Compiler Error CS1612 (编译器错误 CS1612 (C#) )  
看一下就知道了,中文的比英文原版的逊多了  
C# - Struct in a class.. can not access properties of the struct  
延伸阅读: 
CLR Generics Limitation - Modifying Values In Situ In a Container
 
C#: List of struct
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值