我有一些比較2 PropertyInfos和Equals()的代碼。雖然這通常似乎工作,我已經運行到哪裏了相同的底層等兩項反映房地產信息對象一個奇怪的現象是不相等的:.NET PropertyInfos的平等
PropertyInfo prop1, prop2; // both are public and not static
Console.WriteLine(prop1 == prop2); // false ???
Console.WriteLine(Equals(prop1, prop2)); // false ???
Console.WriteLine(prop1.DeclaringType == prop2.DeclaringType); // true
Console.WriteLine(prop1.ReturnType == prop2.ReturnType); // true
Console.WriteLine(prop1.Name == prop2.Name); // true
Console.WriteLine(prop1.DeclaringType.GetProperties().Contains(prop1)); // true
Console.WriteLine(prop2.DeclaringType.GetProperties().Contains(prop2)); // false ???
它看起來像的PropertyInfo實際上並沒有實現equals(),但我認爲.NET緩存反映了成員,以便始終返回相同的實例。你一定會一直看到a.GetType()== b.GetType()。 PropertyInfos不是這種情況嗎?
其他一些注意事項: - 這個古怪的.NET 4運行NUnit測試時發生的,VS2012,x86版本的目標 - 這甚至不發生,因爲我們這樣比較的所有屬性,但它在一個一致的失敗屬性。
任何人都可以解釋這種行爲嗎?
編輯:如果有人有興趣,這裏是EqualityComparison功能我寫的比較MemberInfos:
public class MemberEqualityComparer : EqualityComparer<MemberInfo> {
public override bool Equals(MemberInfo @this, MemberInfo that) {
if (@this == that) { return true; }
if (@this == null || that == null) { return false; }
// handles everything except for generics
if (@this.MetadataToken != that.MetadataToken
|| !Equals(@this.Module, that.Module)
|| this.Equals(@this.DeclaringType, that.DeclaringType))
{
return false;
}
bool areEqual;
switch (@this.MemberType)
{
// constructors and methods can be generic independent of their types,
// so they are equal if they're generic arguments are equal
case MemberTypes.Constructor:
case MemberTypes.Method:
var thisMethod = @this as MethodBase;
var thatMethod = that as MethodBase;
areEqual = thisMethod.GetGenericArguments().SequenceEqual(thatMethod.GetGenericArguments(),
this);
break;
// properties, events, and fields cannot be generic independent of their types,
// so if we've reached this point without bailing out we just return true.
case MemberTypes.Property:
case MemberTypes.Event:
case MemberTypes.Field:
areEqual = true;
break;
// the system guarantees reference equality for types, so if we've reached this point
// without returning true the two are not equal
case MemberTypes.TypeInfo:
case MemberTypes.NestedType:
areEqual = false;
break;
default:
throw new NotImplementedException(@this.MemberType.ToString());
}
public override int GetHashCode(MemberInfo memberInfo) {
if (memberInfo == null) { return 0; }
var hash = @this.MetadataToken
^@this.Module.GetHashCode()
^this.GetHashCode(@this.DeclaringType);
return hash;
}
}
你見過反編譯的代碼嗎? – pylover
@smartcaveman,只要聲明類型相同,你是否打算返回false?我認爲那裏應該有一個「不」。另外,您的Equals方法的最後幾行似乎被切斷,因爲沒有返回語句或關閉大括號。 – Jax