Compiler Error 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
{
    MyStruct ms;
    public MyStruct Size
    {
        get { return ms; }
        set { ms = value; }
    }
}

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;  // CS1612
    }

    public static void Main() 
    {
        MyClass mc = new MyClass();
        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();   
    }
}

请参阅

结构(C# 编程指南)

值类型(C# 参考)

引用类型(C# 参考)