There is a way without modifying the values, using unsafe code and the undocumented __makeref
method:
public static void Main(string[] args)
{
object a = null;
object b = null;
Console.WriteLine(AreSame(ref a, ref b)); // prints False
Console.WriteLine(AreSame(ref a, ref a)); // prints True
}
static bool AreSame<T1, T2>(ref T1 a, ref T2 b)
{
TypedReference trA = __makeref(a);
TypedReference trB = __makeref(b);
unsafe
{
return *(IntPtr*)(&trA) == *(IntPtr*)(&trB);
}
}
Note: The expression *(IntPtr*)(&trA)
relies on the fact that the first field of TypedReference is an IntPtr
pointing to the variable we want to compare. Unfortunately (or fortunately?), there is no managed way to access that field — not even with reflection, since TypedReference
can’t be boxed and, thus, can’t be used with FieldInfo.GetValue
.