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

本文探讨了C#中使用struct时遇到的一个常见陷阱——尝试直接修改通过表达式返回的struct实例的属性。这种情况会导致编译错误CS1612。文章提供了示例代码并介绍了两种解决方案:将struct改为class或通过中间变量来更新struct。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

编译错误 CS1612 

http://blog.youkuaiyun.com/onlyou930/article/details/5568319
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


模块1 Rebuild started: Project: 仓库粉尘检测与安全控制系统的设计A Rebuild target 'Target 1' assembling STARTUP.A51... compiling delay.c... compiling ds1302.c... ..\sources\ds1302.c(7): error C202: 'DS1302_RST': undefined identifier ..\sources\ds1302.c(8): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(15): error C202: 'DS1302_RST': undefined identifier ..\sources\ds1302.c(20): error C202: 'DS1302_IO': undefined identifier ..\sources\ds1302.c(22): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(24): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(30): error C202: 'DS1302_IO': undefined identifier ..\sources\ds1302.c(32): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(34): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(38): error C202: 'DS1302_RST': undefined identifier ..\sources\ds1302.c(45): error C202: 'DS1302_RST': undefined identifier ..\sources\ds1302.c(51): error C202: 'DS1302_IO': undefined identifier ..\sources\ds1302.c(53): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(55): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(60): error C202: 'DS1302_IO': undefined identifier ..\sources\ds1302.c(63): error C202: 'DS1302_IO': undefined identifier ..\sources\ds1302.c(64): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(66): error C202: 'DS1302_CLK': undefined identifier ..\sources\ds1302.c(70): error C202: 'DS1302_RST': undefined identifier compiling dust_sensor.c... compiling oled12864.c... compiling mainA.C... ..\sources\mainA.C(53): warning C206: 'OLED_ShowString': missing function-prototype ..\sources\mainA.C(53): error C267: 'OLED_ShowString': requires ANSI-style prototype ..\sources\mainA.C(83): error C141: syntax error near 'static', expected '__asm' ..\sources\mainA.C(83): error C202: 'init_time': undefined identifier ..\sources\mainA.C(95): error C202: 'init_time': undefined identifier Target not created. Build Time Elapsed: 00:00:01
最新发布
06-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值