【问题标题】:C# 11, Copying system.actionC# 11,复制 system.action
【发布时间】:2022-11-16 02:32:46
【问题描述】:
file class C
{
    public int IntField1;
}

file struct S
{
    public int IntField1;
}

file class StructureVsClassWhenCopying
{
    private static void v1()
    {
        System.Console.WriteLine("v1");
    }

    private static void v2()
    {
        System.Console.WriteLine("v2");
    }

    public static void Main()
    {
        C c1 = new();
        c1.IntField1 = 1;
        C c2 = c1;
        c1.IntField1 = 2;
        System.Console.WriteLine(c2.IntField1); // 2, because class is a reference-type

        S s1 = new();
        s1.IntField1 = 1;
        S s2 = s1;
        s1.IntField1 = 2;
        System.Console.WriteLine(s2.IntField1); // 1, because struct is a value type

        string str1 = "old string";
        string str2 = str1;
        str1 = "new string";
        System.Console.WriteLine(str2); // old string, because string is immutable

        System.Action a1 = v1;
        System.Action a2 = a1;
        a1 -= v1;
        a1 += v2;
        a2.Invoke(); //v1. Why?
    }
}

我想知道引用和值类型的复制。我已经通过类(引用类型)、结构(值类型)和字符串(也是引用类型,但不可变)理解了这个示例。但是委托也是引用类型,为什么它们表现得像结构和字符串?

【问题讨论】:

    标签: c# delegates value-type copying reference-type


    【解决方案1】:

    a1 分配给 a2 意味着您正在复制 a1 中包含的引用,这是对 v1 的引用。 a2 绝不会包含对 a1 的引用。所以改变a1没有效果。

    System.Action a1 = v1;  //a1 points to the v1 method
    System.Action a2 = a1;  //a2 now points to the v1 method too
    a1 -= v1;               //a1 points nowhere
    a1 += v2;               //a1 now points at the v2 method
    a2.Invoke();            //a2 still points at the v1 method
    

    【讨论】:

      【解决方案2】:

      因为代表有他们自己的逻辑。他们是多播代表。您可以将它们视为委托数组。即,您可以添加多个代表。每次添加或删除委托时,您都会得到一个新实例这个数组的回报。这确保了多线程场景中的正确行为。

      例如

      System.Action a1 = v1;
      a1 += v2;
      a1(); ==> Prints "v1" and "v2";
      

      【讨论】:

      • 我可以说代表是不可变的吗?或者这是一个错误?
      • 对,就是这样。很像弦乐。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 2017-08-31
      • 2011-10-29
      相关资源
      最近更新 更多