您的位置:首页 > 编程语言 > C#

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

2016-04-19 20:19 471 查看
无法修改“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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: