获取类实现的接口

luk*_*wid 6 .net c# reflection .net-assembly

我正在做装配分析项目,遇到了问题。

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

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

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> {}
Run Code Online (Sandbox Code Playgroud)

我想得到的是

    typeof(A).GetInterfaces().Dump();  //typeof(IT)
    typeof(B).GetInterfaces().Dump();  //typeof(IT<Int32>) 
    typeof(C).GetInterfaces().Dump();  //
Run Code Online (Sandbox Code Playgroud)

我发现这篇文章Type.GetInterfaces() 对于声明的接口仅带有答案

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

但我正在寻找是否有一种替代方法可以迭代方法。

有什么办法可以实现这一点吗?

Has*_*ngü 5

我尝试将我的答案写得尽可能自我记录。变量名称也可以解释它们在做什么。所以我会让代码来说话:)

\n\n
public static class InterfaceDumperExtension\n{\n\n    public static Type[] DumpInterface(this Type @type)\n    {\n        //From your question, I think that you only want to handle\n        //class case so I am throwing here but you can handle accordingly\n        if (@type.IsClass == false)\n        {\n            throw new NotSupportedException($"{@type} must be a class but it is not!");\n        }\n\n        //All of the interfaces implemented by the class\n        var allInterfaces = new HashSet<Type>(@type.GetInterfaces());\n\n        //Type one step down the hierarchy\n        var baseType = @type.BaseType;\n\n        //If it is not null, it might implement some other interfaces\n        if (baseType != null)\n        {\n            //So let us remove all the interfaces implemented by the base class\n            allInterfaces.ExceptWith(baseType.GetInterfaces());\n        }\n\n        //NOTE: allInterfaces now only includes interfaces implemented by the most derived class and\n        //interfaces implemented by those(interfaces of the most derived class)\n\n        //We want to remove interfaces that are implemented by other interfaces\n        //i.e\n        //public interface A : B{}\n        //public interface B {}\n        //public class Top : A{}\xe2\x86\x92 We only want to dump interface A so interface B must be removed\n\n        var toRemove = new HashSet<Type>();\n        //Considering class A given above allInterfaces contain A and B now\n        foreach (var implementedByMostDerivedClass in allInterfaces)\n        {\n            //For interface A this will only contain single element, namely B\n            //For interface B this will an empty array\n            foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())\n            {\n                toRemove.Add(implementedByOtherInterfaces);\n            }\n        }\n\n        //Finally remove the interfaces that do not belong to the most derived class.\n        allInterfaces.ExceptWith(toRemove);\n\n        //Result\n        return allInterfaces.ToArray();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

测试代码:

\n\n
public interface Interface1 { }\npublic interface Interface2 { }\npublic interface Interface3 { }\npublic interface DerivedInterface1 : Interface1 { }\npublic interface DerivedInterface2 : Interface2 { }\npublic class Test : DerivedInterface1, DerivedInterface2, Interface3 { }\n\nvar result = typeof(Test).DumpInterface();\n//Contains only DerivedInterface1, DerivedInterface2, Interface3 \n
Run Code Online (Sandbox Code Playgroud)\n