将返回值分配给变量时,是否总是进行复制?

问题描述

C# language reference声称

赋值始终将值简单地按位复制到 变量。

对于形式int i = 7;的赋值当然不是正确的,而且我猜想A a = new A(...);中仅创建了一个实例。我想知道是否对ref returns进行了赋值。方法对变量的返回值始终是该返回值的副本(不是在谈论struct A { public int f() { int j = 7; return j; } public int g(out int j) { return j = 7; } } A a = new A(); int jj = a.f(); // Are j and jj aliases? int jjj; a.g(out jjj); // j and jjj are aliases )。返回的局部变量可以安全地重用,因为否则它仍将由GC收集,而无需在方法调用后再次使用。

示例代码

python 3.7.3

解决方法

复制/弹出的内容以及原因取决于您对它们的处理方式,您可以轻松地自己弄清楚。

注意:.Net规范仅具有按值按引用out,是只需ref。因此,正如您所看到的,按照文档

struct A
{
   public unsafe int f()
   {
      int j = 7;
      Console.WriteLine($"j1 \t: {(uint) &j}");
      return j;
   }

   public unsafe int g(out int j)
   {
      j = 7;
      fixed (int* p = &j)
         Console.WriteLine($"j2 \t: {(uint) p}");
      return j;
   }
}

public static unsafe void Main()
{

   A a = new A();
   int jj = a.f(); // Are j and jj aliases?
   Console.WriteLine($"jj \t: {(uint) &jj}");
   int jjj;
   var jjjj = a.g(out jjj); // j and jjj are aliases
   Console.WriteLine($"jjj \t: {(uint) &jjj}");
   Console.WriteLine($"jjjj \t: {(uint) &jjjj}");
}

输出

j1      : 2654464036
jj      : 2654464172
j2      : 2654464160
jjj     : 2654464160
jjjj    : 2654464156

注释2 :您也可以使用Sharp IO来更清楚地了解实际发生的情况,example here