只读vs静态只读说明

时间:2019-03-10 17:29:23

标签: c#

我想了解一个有趣的情况。我的课堂上有一个readonly结构字段。这意味着,当我引用它时,它引用的是副本,而不是实际的副本,因此,当我调用change方法时,它将使用副本,而原始副本将保持不变。

那不是我所观察到的。我只看到带有静态字段的预期行为。我期望这两种类型的行为。

private struct junk
{
    public int i;

    public void change()
    {
        i += 1;
    }
}

private readonly junk jk;
private static readonly junk jk2;

public Form1()
{
    InitializeComponent();
    jk.change();
    //jk.i is now 1, why? Shouldn't it be changing a copy and not the original jk?
    jk2.change();
    //jk2.i is 0
}

1 个答案:

答案 0 :(得分:6)

  

我的课堂上有一个只读的struct字段。这意味着,当我引用它时,它引用的是副本而不是实际副本,因此,当我调用change方法时,它将使用副本,而原始副本将保持不变。

这根本不是readonly修饰符所做的。 readonly修饰符可防止您在构造函数之外的任何地方为jk分配新值。然后,static修饰符使您可以独立于所使用的Form1的实例重用该值。
就是说,readonlystatic都没有做出您正在描述的怪异行为,因为确切的行为无法用您发布的代码来再现。

在控制台应用程序中查看一个更简单的示例(您可以尝试here):

public class Program
{
    private readonly junk jk;
    private static readonly junk jk2;

    public static void Main()
    {
        var program = new Program();
        program.jk.change();
        Console.WriteLine(program.jk.i); // prints 0

        jk2.change();
        Console.WriteLine(jk2.i); // prints 0
    }
}

public struct junk
{
    public int i;
    public void change()
    {
        i += 1;
    }
}

然后,如@Damien_The_Unbeliever所评论的那样,尝试尽可能避免产生可变的struct