那么,一个肮脏的方式可能是手动检查方法签名是否匹配。
检查签名可能是这样一种方法:
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