编译器错误 CS1612
无法修改“expression”的返回值,因为它不是变量
尝试修改某一值类型,该值类型作为中间表达式的结果生成但不存储于变量中。 如果尝试直接修改泛型集合中的结构,则会发生此错误,如下例所示:
List<MyStruct> list = {…};
list[0].Name = "MyStruct42"; //CS1612
若要修改结构,请首先将其赋给局部变量,修改该变量,然后将变量赋回集合中的项。
List<MyStruct> list = {…};
MyStruct ms = list[0];
ms.Name = "MyStruct42";
list[0] = ms;
之所以会发生此错误,原因是在赋值时复制了值类型。 在从属性或索引器中检索值类型时,所获取的是对象的副本,而不是对于对象本身的引用。 返回的副本不由属性或索引器存储,因为它们实际上是方法,而不是存储位置(变量)。 必须将副本存储在声明的变量中,然后才能对其进行修改。
引用类型不会发生此错误,因为在这种情况下,属性或索引器将返回对现有对象的引用,该对象是存储位置。
如果是在定义类或结构,则修改属性声明,提供对结构成员的访问,即可解决此错误。 如果是在编写客户端代码,则创建你自己的结构实例,修改其字段,然后将整个结构赋回给该属性,即可解决此错误。 第三种替代方式是,可以将结构更改为类。
示例
尝试通过将返回整个结构的封闭类中的属性访问结构成员时,也会出现 CS1612,如下面的示例中所示:
// CS1612.cs
using System;
public struct MyStruct
{
public int Width;
}
public class ListView
{
public MyStruct Size { get; set; }
}
public class MyClass
{
public MyClass()
{
ListView lvi;
lvi = new ListView();
lvi.Size.Width = 5; // CS1612
// You can use the following lines instead.
// MyStruct ms;
// ms.Width = 5;
// lvi.Size = ms;
}
public static void Main()
{
MyClass mc = new MyClass();
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}