今天,寫程式的時候,遇到 Cannot modify the return value of ...,because it is not a variable 這個錯誤.糾結了一個多小時,.因為按我人常規去寫程式,程式看起來是對的.
但編譯會提示出這個錯誤.
後來,要csnd上找到了微軟的解釋.是這樣的.
---------------------------------------------------------------------------------------------
錯誤出現的原因:
在類中定義了結構體,結構體有C#庫中的執行個體,然後在後面的過程以試圖對這個執行個體進行修改是個會出現.
需要注意的是:
<1>必須是在類中定義的結構體;
<2>結構體中必須包含了C#類庫中的執行個體;
注意:這裡說的執行個體只包含直接執行個體,比如:Point執行個體,不包含序列執行個體,比如List<Point>也就是說後面這種是好使的,原因會在後面的分析中說明.
<3>在後面的代碼中嘗試了對該執行個體修改.
---------------------------------------------------------------------------------------------
錯誤描述與分析:
錯誤出現的原因是:C#.Struct中對C#類的執行個體的訪問操作返回的是副本(中間值),也就是說,直接的調用是唯讀,VS編譯器直接拒絕這麼做,所以給出提示(因為它本身的值是沒有改變,改變的只是中間值).而對於容器類型的,在struct中它直接就是以引用形式存在的,所以不會出發現這種問題.具體例子參考:
csdn:http://msdn.microsoft.com/en-us/library/wydkhw2c(vs.71).aspx
如下:
錯誤的解決方案:
<1>可以使用class代替struct(推薦)
<2>其它方法就要從它出現的原因分析入手了.
csdn中的描述如下:
Cannot modify the return value of 'expression' because it is not a variable
An attempt was made to modify a value type that was the result of an intermediate expression. Because the value is not persisted, the value will be unchanged.
To resolve this error, store the result of the expression in an intermediate value, or use a reference type for the intermediate expression.
The following sample generates CS1612:
Copy
// CS1612.csclass Reference{ public int i; public int Prop { get { return i; } set { i = value; } } public override string ToString() { return "i = " + i.ToString(); }}struct Value{ public int i; public int Prop { get { return i; } set { i = value; } } public override string ToString() { return "i = " + i.ToString(); }}class Example{ private Reference _r; // Reference type private Value _v; // Value type public Example() { _r = new Reference(); _v = new Value(); } public Reference RefProp { get { return _r; } set { _r = value; } } public Value ValueProp { get { return _v; } set { _v = value; } } public static void Main() { Example e = new Example(); System.Console.WriteLine(e.RefProp); // Prints 0 e.RefProp.i = 5; // Legal System.Console.WriteLine(e.RefProp); // Prints 5 e.RefProp.Prop = 6; // Legal System.Console.WriteLine(e.RefProp); // Prints 6 System.Console.WriteLine(e.ValueProp); // Prints 0 // Invalid because ValueProp returns a value on the stack, // and although you could set that value, // it doesn't reflect back into the original property. e.ValueProp.i = 7; // CS1612 // If the above statment was allowed, this would still print 0. System.Console.WriteLine(e.ValueProp); // Invalid because ValueProp returns a value on the stack, // and although you could set that value, // it doesn't reflect back into the original property. e.ValueProp.Prop = 8; // CS1612 // If the above statement was allowed, this would still print 0. System.Console.WriteLine(e.ValueProp); Value v = e.ValueProp; v.i = 9; System.Console.WriteLine(v); // Prints 9 System.Console.WriteLine(e.ValueProp); // Still prints 0 v.Prop = 10; System.Console.WriteLine(v); // Prints 10 System.Console.WriteLine(e.ValueProp); // Still prints 0 e.ValueProp = v; // The following line prints 10 (this is the proper way). System.Console.WriteLine(e.ValueProp); }}