Reference equality of value types

后端 未结 4 1013
臣服心动
臣服心动 2020-12-30 21:06

I have made some ref keyword tests and there is one think I can\'t understand:

static void Test(ref int a, ref int b)
{
    Console.WriteLine(In         


        
4条回答
  •  猫巷女王i
    2020-12-30 22:02

    Why does this code display False?

    Because int a and int b are being boxed when you call object.ReferenceEquals. Each integer is boxed inside an object instance. Thus, you are actually comparing references between two boxed values, which clearly aren't equal.

    You can easily see this if you look at the generated CIL for the method:

    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
    

    Checking for storage location equality can be achieved either by using verifiable CIL (such as in @leppie's answer) or by unsafe code:

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

提交回复
热议问题