class A {
public virtual void Func() { }
}
class B : A {
public override void Func() => base.Func();
}
class C : B {
public override void Func() => base.Func();
}
var type = typeof( C );
var method = type.GetMethod( "Func" );
method.GetBaseDefinition().DeclaringType.Name // A
method.GetRuntimeBaseDefinition().DeclaringType.Name // A
GetBaseDefinition
返回A类的方法。但是我需要B类的方法。
有可能吗?
答案 0 :(得分:1)
您可以使用某些给定类型的反射和遍历继承树,按类型:
public static Type GetMethodDeclaringTypeClosestInHierarchy(MethodInfo derivedTypeMethod)
{
//Method is not virtual, you have the only definition in inheritance tree
if (!derivedTypeMethod.IsVirtual) return derivedTypeMethod.DeclaringType;
var baseType = derivedTypeMethod.DeclaringType.BaseType;
while (baseType != null)
{
//Check if in base type there is a method
if (baseType.GetMethods().Any(baseTypeMethod =>
//that has same base definition like then one we're checking
baseTypeMethod.GetBaseDefinition() == derivedTypeMethod.GetBaseDefinition()
//and is actually overriden in baseType
&& baseTypeMethod.DeclaringType == baseType))
{
return baseType;
}
//If not, go on higher in inheritance tree
baseType = baseType.BaseType;
}
//Found nothing
return derivedTypeMethod.DeclaringType;
}
斯科特答案的问题是,当您在继承树中有两个签名不同但名称相同的方法时:
class A
{
public virtual void Func() { }
public virtual string Func(string test) { return ""; }
}
class B : A
{
public override string Func(string test) => base.Func(test);
public override void Func() => base.Func();
}
class C : B
{
public override void Func() => base.Func();
}
您将获得System.Reflection.AmbiguousMatchException: 'Ambiguous match found.'
typeof(B).GetMethod("Func",
BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
static void Main(string[] args)
{
var type = typeof(C);
//This will throw with multiple methods of given name:
var method1 = type.GetMethod("Func");
//This will not but you need to be pretty explicit on what you're searching for
var method2 = type.GetMethods().SingleOrDefault(m => m.Name == "Func" && m.ReturnType == typeof(void));
var result = GetMethodDeclaringTypeClosestInHierarchy(method2);
Console.WriteLine(result);
Console.ReadKey();
}
答案 1 :(得分:0)
A
,B
和C
之间存在继承关系。但是,各个类中的方法之间没有这种关系。 C
不会覆盖B
中的方法,而是覆盖A
中的方法。这就是为什么该方法除了最初声明的定义之外不会提供任何基本定义的原因。
...返回直接或间接基类上方法的MethodInfo对象,在该基类中,首先声明此实例表示的方法。
如果您想在C
的直接基类中找到该方法的实现,那么您将找出该类型是什么,然后在那里寻找该方法。
var type = typeof(C);
var baseType = type.BaseType;
var method = baseType.GetMethod("Func");
如果找到方法,则不一定在B
中声明它。没有任何话说B
必须具有该方法。如果不是,则上述方法将从A
返回该方法。
如果只想<{>} B
中声明的内容,则可以这样做:
var method = baseType.GetMethod("Func",
BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
DeclaredOnly
表示必须在B
中声明,而不是B
继承。
现在,如果有一个方法,您将从B
获取该方法;如果没有在B
中重写该方法,则为null。