繁体   English   中英

反思:如何获取基础方法(不是原始方法)?

[英]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类的方法。

可能吗?

ABC之间存在继承关系。 但是各个类中的方法之间没有这种关系。 C没有覆盖B中的方法 - 它覆盖了A中的方法。 这就是为什么该方法不会为您提供除第一次声明之外的任何基本定义。

MethodInfo.GetBaseDefinition

... 返回直接或间接基类上的方法的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM