获取由类实现的接口 [英] Get interfaces implemented by class

查看:167
本文介绍了获取由类实现的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个组装分析项目,遇到一个问题。

I'm doing assembly analysis project and I encountered a problem.

我想要实现的是一个类实现的所有接口的列表,但是没有派生的接口(以及由派生类实现的接口)。

What I want to achieve is list of all interfaces implemented by a class, but without derived interfaces (and interfaces implemented by derived classes).

下面是一个示例说明(从LinqPad中, .Dump()是打印到结果的窗口):

Here's an example to illustrate (from LinqPad, .Dump() is a printing to result window):

void Main()
{
    typeof(A).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>) 
    typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>) 
    typeof(C).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>) 
}

class C : A {}

class A : IT {}

class B : IT<int> {}

public interface IT : IT <int> {}

public interface IT<T> {}

我想得到的是

    typeof(A).GetInterfaces().Dump();  //typeof(IT)
    typeof(B).GetInterfaces().Dump();  //typeof(IT<Int32>) 
    typeof(C).GetInterfaces().Dump();  //

我发现了此帖子 Type.GetInterfaces()仅用于声明的接口,带有答案

I found this post Type.GetInterfaces() for declared interfaces only with an answer

Type type = typeof(E);
var interfaces = type.GetInterfaces()
    .Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
    .ToList();

但是我在寻找是否有迭代方法的替代方法。

But I'm looking if there is an alternative that iterating through methods.

有什么方法可以实现?

Is there any way to achieve this?

推荐答案

我试图将自己的答案写成自我记录。变量名也可以解释他们在做什么。 。因此,我将让代码开始讨论:)

I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)

public static class InterfaceDumperExtension
{

    public static Type[] DumpInterface(this Type @type)
    {
        //From your question, I think that you only want to handle
        //class case so I am throwing here but you can handle accordingly
        if (@type.IsClass == false)
        {
            throw new NotSupportedException($"{@type} must be a class but it is not!");
        }

        //All of the interfaces implemented by the class
        var allInterfaces = new HashSet<Type>(@type.GetInterfaces());

        //Type one step down the hierarchy
        var baseType = @type.BaseType;

        //If it is not null, it might implement some other interfaces
        if (baseType != null)
        {
            //So let us remove all the interfaces implemented by the base class
            allInterfaces.ExceptWith(baseType.GetInterfaces());
        }

        //NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
        //interfaces implemented by those(interfaces of the most derived class)

        //We want to remove interfaces that are implemented by other interfaces
        //i.e
        //public interface A : B{}
        //public interface B {}
        //public class Top : A{}→ We only want to dump interface A so interface B must be removed

        var toRemove = new HashSet<Type>();
        //Considering class A given above allInterfaces contain A and B now
        foreach (var implementedByMostDerivedClass in allInterfaces)
        {
            //For interface A this will only contain single element, namely B
            //For interface B this will an empty array
            foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
            {
                toRemove.Add(implementedByOtherInterfaces);
            }
        }

        //Finally remove the interfaces that do not belong to the most derived class.
        allInterfaces.ExceptWith(toRemove);

        //Result
        return allInterfaces.ToArray();
    }
}

测试代码:

public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }

var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3 

这篇关于获取由类实现的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆