使用.NET Framework 3.5的Equals
方法比較MethodBase
情況下,當我遇到一個相當奇怪的行爲 - 它只是失敗的情況下,NullReferenceException
比較編譯器定義時帶有開放式泛型方法對象的構造器方法對象。System.Reflection.RuntimeMethodInfo.Equals失敗,NullReferenceException異常在.net 3.5
這裏是攝製代碼:
class TheClass
{
public T TheMethod<T>()
{
return default(T);
}
}
class Program
{
private static void Main(string[] args)
{
var ctor = typeof(TheClass).GetConstructors().Single();
var generic = typeof(TheClass).GetMethods().Single(x => x.Name == "TheMethod");
Console.WriteLine(generic.Name); // TheMethod
Console.WriteLine(generic.GetType().Name); // RuntimeMethodInfo
Console.WriteLine(ctor.Name); // .ctor
Console.WriteLine(ctor.GetType().Name); // RuntimeConstructorInfo
Console.WriteLine(generic.Equals(ctor)); // throws NullReferenceException
Console.ReadKey();
}
}
它工作正常,在.NET 4.0中。 我一直在使用反編譯看着RuntimeMethodInfo.Equals
實現在3.5和4.0,這是一個有趣的部分:
.NET 3.5
if (!this.IsGenericMethod)
return obj == this;
RuntimeMethodInfo runtimeMethodInfo = obj as RuntimeMethodInfo;
if (this.GetMethodHandle().StripMethodInstantiation() != runtimeMethodInfo.GetMethodHandle().StripMethodInstantiation() || runtimeMethodInfo == null || !runtimeMethodInfo.IsGenericMethod)
return false;
// ...
.NET 4.0
if (!this.IsGenericMethod)
return obj == this;
RuntimeMethodInfo runtimeMethodInfo = obj as RuntimeMethodInfo;
if ((MethodInfo) runtimeMethodInfo == (MethodInfo) null || !runtimeMethodInfo.IsGenericMethod || RuntimeMethodHandle.StripMethodInstantiation((IRuntimeMethodInfo) this).Value.Value != RuntimeMethodHandle.StripMethodInstantiation((IRuntimeMethodInfo) runtimeMethodInfo).Value.Value)
return false;
在.NET 4.0 null
-check使用可能的空runtimeMethodInfo
變量之前被感動了。對我而言,3.5行爲似乎是一個框架bug,不是嗎?
所以問題是 - 有沒有解決方法或安全地比較這些對象的方法?請注意,在實際的代碼,我沒有要求Equals
直接,但在收藏品等使用它隱含的地方,所以捕NullReferenceExceptions
聽起來並不好。
有沒有什麼不能切換到.NET 4的理由?我知道這不是一個答案,但它是一個解決方案。 – ChrisF
看起來好像沒有一個好的解決方法,除了編寫替代的'Equals'方法外。或者至少在調用運行時的「Equals」方法之前檢查'ctor'值。你可以爲你的集合創建一個'EqualityComparer',這樣它就不會調用運行時版本。 –
@ChrisF我不想切換,因爲這是更類似庫的項目,我不想要消費者需要.NET 4。 – NOtherDev