天天看點

C# struct的陷阱:無法修改“...”的傳回值,因為它不是變量

C# struct的陷阱:無法修改“...”的傳回值,因為它不是變量

編譯錯誤 CS1612 

http://blog.csdn.net/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

C# struct的陷阱:無法修改“...”的傳回值,因為它不是變量
C# struct的陷阱:無法修改“...”的傳回值,因為它不是變量

繼續閱讀