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)
但我正在寻找是否有一种替代方法可以迭代方法。
有什么办法可以实现这一点吗?
我尝试将我的答案写得尽可能自我记录。变量名称也可以解释它们在做什么。所以我会让代码来说话:)
\n\npublic 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}\nRun Code Online (Sandbox Code Playgroud)\n\n测试代码:
\n\npublic 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 \nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
6258 次 |
| 最近记录: |