C#中的值类型和引用类型在相等性的判定上是不同的
以Object.Equal方法为例,值类型判定的是值相等(及所有成员相等,会在成员上调用递归调用Equal方法);而引用类型默认则是判断引用相等(及两个变量指向托管堆中的同一个对象)
先列出值类型基类(ValueType)重写的Equal代码(其中有两个重要的函数有[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]属性,用Reflector看不到代码,还望大牛指点)
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
RuntimeType type = (RuntimeType) base.GetType();
RuntimeType type2 = (RuntimeType) obj.GetType();
if (type2 != type)
{
return false;
}
object a = this;
if (CanCompareBits(this))
{
return FastEqualsCheck(a, obj);
}
FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < fields.Length; i++)
{
object obj3 = ((RtFieldInfo) fields[i]).InternalGetValue(a, false);
object obj4 = ((RtFieldInfo) fields[i]).InternalGetValue(obj, false);
if (obj3 == null)
{
if (obj4 != null)
{
return false;
}
}
else if (!obj3.Equals(obj4))
{
return false;
}
}
return true;
}引用类型重写Equal方法即能判断值相等性;
==运算符默认判断引用相等,也可重写(重写==,必须同时重写!=);
class TestB
{
public Int32 i;
public Single s;
public override bool Equals(object obj)
{
TestB other = obj as TestB;
if (other == null)
{
return false;
}
return (i == ((TestB)obj).i && s == ((TestB)obj).s);
}
public static bool operator ==(TestB lhs, TestB rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(TestB lhs, TestB rhs)
{
// return lhs.Equals(rhs);
return !(lhs == rhs);
}
}Object.ReferenceEqual静态方法则只能判断引用相等
本文探讨了C#中值类型和引用类型的等价性判定方法。详细解释了Object.Equal方法如何应用于不同类型,并展示了通过重写Equals方法实现值类型的相等性比较。此外,文章还介绍了==运算符的行为以及Object.ReferenceEqual方法的使用。
872

被折叠的 条评论
为什么被折叠?



