获取 class 实现的接口
Get interfaces implemented by class
我在做汇编分析项目,遇到了问题
我想要实现的是 class 实现的所有接口的列表,但没有派生接口(以及派生 classes 实现的接口)。
这里有一个例子来说明(来自LinqPad,.Dump()
是打印到结果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(); //
我发现这个 post Type.GetInterfaces() for declared interfaces only 有答案
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
但我正在寻找是否有迭代方法的替代方法。
有什么办法可以实现吗?
我试图将我的答案写成自我记录的形式,因为 possible.Variables 名字也可以解释他们在做什么。所以我会让代码来说话:)
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
我在做汇编分析项目,遇到了问题
我想要实现的是 class 实现的所有接口的列表,但没有派生接口(以及派生 classes 实现的接口)。
这里有一个例子来说明(来自LinqPad,.Dump()
是打印到结果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(); //
我发现这个 post Type.GetInterfaces() for declared interfaces only 有答案
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
但我正在寻找是否有迭代方法的替代方法。
有什么办法可以实现吗?
我试图将我的答案写成自我记录的形式,因为 possible.Variables 名字也可以解释他们在做什么。所以我会让代码来说话:)
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