[英]Reflection: How to get base method (not original method)?
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类的方法。
可能吗?
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 。
您可以使用一些给定类型的反射和遍历继承树,按类型键入:
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.