c# - 值类型的引用相等性

标签 c# ref boxing

我做了一些 ref 关键字测试,但有一件事我无法理解:

static void Test(ref int a, ref int b)
{
    Console.WriteLine(Int32.ReferenceEquals(a,b));
}

static void Main(string[] args)
{
    int a = 4;
    Test(ref a, ref a);
    Console.ReadLine();
}

为什么这段代码显示False?我知道 int 是一个值类型,但在这里它应该传递对同一对象的引用。

最佳答案

Why does this code display False?

因为 int aint b are being boxed当你调用object.ReferenceEquals .每个整数都装在一个 object 实例中。因此,您实际上是在比较两个装箱值之间的引用,这两个值显然不相等。

如果您查看生成的 CIL,您可以很容易地看到这一点对于方法:

Test:
IL_0000:  nop
IL_0001:  ldarg.0     Load argument a
IL_0002:  ldind.i4
IL_0003:  box         System.Int32
IL_0008:  ldarg.1     Load argument b
IL_0009:  ldind.i4
IL_000A:  box         System.Int32
IL_000F:  call        System.Object.ReferenceEquals
IL_0014:  call        System.Console.WriteLine
IL_0019:  nop
IL_001A:  ret

可以通过使用可验证的 CIL(例如 @leppie's answer)或 unsafe 代码来检查存储位置是否相等:

unsafe static void Main(string[] args)
{
    int a = 4;
    int b = 5;
    Console.WriteLine(Test(ref a, ref a)); // True
    Console.WriteLine(Test(ref a, ref b)); // False;
}

unsafe static bool Test(ref int a, ref int b)
{
    fixed (int* refA = &a)
    fixed (int* refB = &b)
    {
        return refA == refB;
    }
}

关于c# - 值类型的引用相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31266947/

相关文章:

c# - 另一个进程使用的文件c#

c# - 我的图像不会添加 C#

c# - 在没有引用的情况下覆盖参数的通用方法?

reactjs - 在 React 中,ref 是引用虚拟 DOM 还是实际 DOM?

c# - C# 中动态数据类型的装箱和拆箱工作原理

具有尾递归优化的 C# 编译?

c# - 删除循环中的控件

numpy - 如何在 Python 3.3 的 numpy 中启用 nditer 中的 REFS_OK 标志?

通过引用传递结构时 C# 框或副本?