6
System.Reflection.Type包含GetInterfaceMap這有助於確定從接口實現某種方法的方法。Mono.Cecil類似於Type.GetInterfaceMap?
是否Mono.Cecil包含這樣的內容? 或者如何實現這樣的行爲?
System.Reflection.Type包含GetInterfaceMap這有助於確定從接口實現某種方法的方法。Mono.Cecil類似於Type.GetInterfaceMap?
是否Mono.Cecil包含這樣的內容? 或者如何實現這樣的行爲?
不,塞西爾不提供這樣的方法,因爲塞西爾給我們提供的只是CIL元數據。 (有項目Cecil.Rocks,其中包含了一些有用的擴展方法,但不是這個)
在MSIL方法有一個屬性「覆蓋」,其中包含的方法的引用,這種方法覆蓋(塞西爾的確有MethodDefinition類中的屬性覆蓋)。但是,該屬性僅用於某些特殊情況,如顯式接口實現。通常這個屬性是空的,並且所討論的方法覆蓋哪些方法是基於約定的。這些約定在ECMA CIL標準中進行了描述。簡而言之,一種方法會覆蓋具有相同名稱和相同簽名的方法。
下面的代碼片段可以幫助你和這個討論:http://groups.google.com/group/mono-cecil/browse_thread/thread/b3c04f25c2b5bb4f/c9577543ae8bc40a
public static bool Overrides(this MethodDefinition method, MethodReference overridden)
{
Contract.Requires(method != null);
Contract.Requires(overridden != null);
bool explicitIfaceImplementation = method.Overrides.Any(overrides => overrides.IsEqual(overridden));
if (explicitIfaceImplementation)
{
return true;
}
if (IsImplicitInterfaceImplementation(method, overridden))
{
return true;
}
// new slot method cannot override any base classes' method by convention:
if (method.IsNewSlot)
{
return false;
}
// check base-type overrides using Cecil's helper method GetOriginalBaseMethod()
return method.GetOriginalBaseMethod().IsEqual(overridden);
}
/// <summary>
/// Implicit interface implementations are based only on method's name and signature equivalence.
/// </summary>
private static bool IsImplicitInterfaceImplementation(MethodDefinition method, MethodReference overridden)
{
// check that the 'overridden' method is iface method and the iface is implemented by method.DeclaringType
if (overridden.DeclaringType.SafeResolve().IsInterface == false ||
method.DeclaringType.Interfaces.None(i => i.IsEqual(overridden.DeclaringType)))
{
return false;
}
// check whether the type contains some other explicit implementation of the method
if (method.DeclaringType.Methods.SelectMany(m => m.Overrides).Any(m => m.IsEqual(overridden)))
{
// explicit implementation -> no implicit implementation possible
return false;
}
// now it is enough to just match the signatures and names:
return method.Name == overridden.Name && method.SignatureMatches(overridden);
}
static bool IsEqual(this MethodReference method1, MethodReference method2)
{
return method1.Name == method2.Name && method1.DeclaringType.IsEqual(method2.DeclaringType);
}
// IsEqual for TypeReference is similar...
可否請您提供缺少的`SignatureMatches`方法?這是一件複雜的事情,因爲它必須將通用參數和參數視爲不易比較的參數。 – ygoe 2015-11-06 19:55:34