我做了一些 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 a
和 int 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/