【问题标题】:How detect is a method in a C# class is implementing a method from an interface?如何检测 C# 类中的方法是否从接口实现方法?
【发布时间】:2019-05-08 20:10:26
【问题描述】:

我希望能够使用反射来判断SomClassImpl 中方法GetName 的实现来自接口IHasName。举个例子:

public interface IHasName
{
    string GetName();
}

public interface IOtherInterface
{
    //...elided...
}

public class MyClass : IHasName, IOtherInterface
{
    /*
     * I want to use reflection to know this 
     * implements IHasName.GetName()
     */
    public string GetName()
    {
        return "me";
    }
}

这可能吗?

当我尝试typeof(MyClass).GetMethod("GetName").GetBaseDefinition().DeclaringTypetypeof(MyClass).GetMethod("GetName").DeclaringType 时,它们都返回实现类,不是接口。

【问题讨论】:

  • 除非MyClass是抽象的,难道不是必须实现GetName吗?什么时候会出现没有实现但仍然实现接口的情况?我知道新的 C# 版本有接口实现,但我认为这是将实现插入派生类的语法糖......
  • @RonBeyer 我想我不清楚,抱歉。我不需要知道它实现了接口“X”。我想知道,“这个方法来自接口 X,这个方法来自接口 Y,这个方法只来自即将到来的类”
  • var iFC = myClass.GetType().GetInterfaces().FirstOrDefault(ifc => ifc.GetMethods().Any(m => m.Name.Equals("[MethodName]")));。或使用myClass.GetType().GetMethods() 找到的值。
  • @DonRhummy 您可能想在edit 发帖解释 GetInterfaceMap 如何/为什么不起作用...

标签: c# .net reflection


【解决方案1】:

我看到您的情况发生的两种可能性:

  1. 类实现接口
  2. 类继承了实现接口的类

在前一种情况下,typeof(Foo).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindiFoongFlags.DeclaredOnly) 返回方法信息。

在后一种情况下,typeof(Bar).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) 返回null

an example here

【讨论】:

    【解决方案2】:

    下面会告诉对象是否实现了接口:

    unkObj is IHasName
    

    如果在类型而不是对象上使用反射,这也是如此:

    typeof(IHasName).IsAssignableFrom(typeof(MyClass))
    

    这将获取与接口关联的方法,并使用任何实现该接口的类型调用它,并在其类中调用关联的方法:

    MethodInfo methodIHasName = typeof(IHasName).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
    string name = methodIHasName.Invoke(unkObj, new object[0]);
    

    如果你绝对需要得到MyClassMethodInfo,而你只有接口IHasNameMethodInfo,你可以将接口映射如下:(Thanks @Alexei Levenkov for the link)

    var map = typeof(MyClass).GetInterfaceMap(methodIHasName.DeclaringType);
    var index = Array.IndexOf(map.InterfaceMethods, methodIHasName);
    return map.TargetMethods[index];
    

    【讨论】:

    • 这是正确的答案,因为另一个假设接口方法以相同的名称实现,但不考虑显式实现。
    猜你喜欢
    • 2014-04-12
    • 2023-04-06
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    相关资源
    最近更新 更多