那麼,一個骯髒的方式可能是手動檢查方法簽名是否匹配。
檢查簽名可能是這樣一種方法:
public static bool HasSameSignature(MethodInfo potentiallyHidingMethod, MethodInfo baseMethod)
{
//different name, therefore not same signature
if (potentiallyHidingMethod.Name != baseMethod.Name)
return false;
//now we check if they have the same parameter types...
var potentiallyHidingMethodParameters = potentiallyHidingMethod.GetParameters();
var baseMethodParameters = baseMethod.GetParameters();
//different number of parameters, therefore not same signature
if (potentiallyHidingMethodParameters.Length != baseMethodParameters.Length)
return false;
for (int i = 0; i < potentiallyHidingMethodParameters.Length; i++)
{
//if a parameter type doesn't match, it's not the same signature
if (potentiallyHidingMethodParameters[i].ParameterType != baseMethodParameters[i].ParameterType)
return false;
}
//if we've gotten this far, they have the same name and parameters,
//therefore, it's the same signature.
return true;
}
然後,它的檢查派生的接口方法,看看他們是否隱藏(或相匹配的簽名)的事項的任何的底座接口方法:
Type type = typeof(IInterfaceWithNewMethod);
var potentiallyHidingMethods = type.GetMethods();
var baseTypeMethods =type.GetInterfaces()
.SelectMany(@interface => @interface.GetMethods());
var hidingMethods = potentiallyHidingMethods
.Where(hiding => baseTypeMethods.Any(baseMethod => HasSameSignature(hiding, baseMethod)));
請注意,這是一個天真的實現。如果有一個更簡單的方法或角落案例,我不會感到驚訝。
編輯:稍微誤解了所需的輸出。使用上面的代碼,這會給你所有的基本接口的方法,再加上衍生的接口中的方法,但篩選出來,由派生的接口隱藏任何基接口方法:
var allMethodsButFavouringHiding = potentiallyHidingMethods.Concat(
baseTypeMethods.Where(baseMethod => !potentiallyHidingMethods.Any(potentiallyhiding => HasSameSignature(potentiallyhiding, baseMethod))));
EDITx2:我沒有給出一個測試以下接口:
public interface IBaseInterface
{
string BaseMethodTokeep();
string MethodToHide();
string MethodSameName();
}
public interface IInterfaceWithNewMethod : IBaseInterface
{
new string MethodToHide();
new string MethodSameName(object butDifferentParameters);
string DerivedMethodToKeep();
}
這導致與MethodInfo
集合:
MethodToHide (IInterfaceWithNewMethod)
MethodSameName (IInterfaceWithNewMethod)
DerivedMethodToKeep (IInterfaceWithNewMethod)
BaseMethodTokeep (IBaseInterface)
MethodSameName (IBaseInterface)
所以它使任何基本接口實現方法具沒有隱藏的ds,任何派生的接口方法(隱藏或其他方式),並且尊重任何簽名更改(即不會導致不隱藏的不同參數)。
EDITx3:增加了另外一個測試用的重載:
public interface IBaseInterface
{
string MethodOverloadTest();
string MethodOverloadTest(object withParam);
}
public interface IInterfaceWithNewMethod : IBaseInterface
{
new string MethodOverloadTest();
}
有了結果:
MethodOverloadTest() for IInterfaceWithNewMethod
MethodOverloadTest(object) for IBaseInterface
我不明白,沒有新的關鍵字也,它會表現得同樣的權利? AFAIK在應用'new'關鍵字方面沒有任何區別。我錯過了什麼嗎?什麼是最終目標? – 2014-09-06 13:55:02
@SriramSakthivel是的,「新」關鍵字是可選的。重要的是一種方法會影響另一種方法。我正在研究AutoFixture的[這個問題](https://github.com/AutoFixture/AutoFixture/issues/306),我需要能夠使用反射來設置模擬接口的所有方法及其基礎接口。但是,如果一個方法影響另一個,我必須*不*設置陰影方法。 – dcastro 2014-09-06 13:58:23