C# 是否仅查找非继承接口?
我试图通过反射对类的接口执行查询,但是方法Type.GetInterfaces()也返回所有继承的接口 等 代码C# 是否仅查找非继承接口?,c#,.net,reflection,.net-4.0,interface,C#,.net,Reflection,.net 4.0,Interface,我试图通过反射对类的接口执行查询,但是方法Type.GetInterfaces()也返回所有继承的接口 等 代码 typeof(Test).GetInterfaces(); 将返回一个类型[],该类型同时包含ITest和ITest,其中我只需要ITest,是否有其他方法允许您指定继承 谢谢, 亚历克斯 编辑: 从下面的答案中我收集到了这个 Type t; t.GetInterfaces().Where(i => !t.GetInterfaces().Any(i2 => i2.Get
typeof(Test).GetInterfaces();
将返回一个类型[]
,该类型同时包含ITest
和ITest
,其中我只需要ITest
,是否有其他方法允许您指定继承
谢谢,
亚历克斯
编辑:
从下面的答案中我收集到了这个
Type t;
t.GetInterfaces().Where(i => !t.GetInterfaces().Any(i2 => i2.GetInterfaces().Contains(i)));
上述方法似乎有效,如果没有,请在评论中更正我尝试以下方法:
Type t = typeof(Test);
int max = 0;
Type result = null;
foreach (Type type in t.GetInterfaces())
{
int len = type.GetInterfaces().Length;
if (len > max)
{
max = len;
result = type;
}
}
if (result != null)
Console.WriteLine(result.FullName);
如果我错了,一个更大的.NET专家可以纠正我,但我认为这是不可能的。在内部,我认为.NET框架实际上并没有维护这种层次结构,当它被编译成IL代码时,它会变得扁平化 例如,C代码: 在内置到IL代码中后,它是:
.class private auto ansi beforefieldinit ReflectionTest.Program
extends [mscorlib]System.Object
implements ReflectionTest.I2,
ReflectionTest.I1
{
...
这与类程序完全相同:I1、I2
然而,在IL中也包括:
.class interface private abstract auto ansi ReflectionTest.I2
implements ReflectionTest.I1
{
...
这意味着您可以编写一些逻辑(从我的示例中)从Program
类中获取I1
和I2
,然后查询这些接口中的每一个,看看它们是否实现了其他接口之一。。。
换句话说,由于typeof(I2).GetInterfaces()包含I1
,那么您可以推断因为typeof(Program).GetInterfaces()返回I1
和I2
,那么Program
可能不会直接继承代码中的I1
我强调可能不是因为这也是有效的C#代码,并且将生成相同的IL代码(以及相同的反射结果):
现在Program
直接和间接继承了I1
…在我以前的尝试中,我没有成功
Type[] types = typeof(Test).GetInterfaces();
var directTypes = types.Except
(types.SelectMany(t => t.GetInterfaces()));
foreach (var t in directTypes)
{
}
希望这将对某人有所帮助。似乎没有简单的方法调用来完成这项工作,因为编译时基本上以下内容完全相同:
MyClass : IEnumerable<bool>
MyClass:IEnumerable
及
MyClass:IEnumerable,IEnumerable
您可以询问每个接口并询问其接口。看看他们是否在前一份名单上。不同寻常的是,对于类来说,getInterface是递归的。也就是说,它获得了所有级别的继承。对于接口,它不是递归的。例如:
IList
返回IList
和ICollection
,但没有提到由ICollection
实现的IEnumerable
但是,您很可能对每个接口唯一实现的方法及其绑定感兴趣,在这种情况下,您可以使用方法GetInterfaceMap(Type)
Type t=typeof(Test);
int max=0;
列表结果=新列表();
foreach(在t.GetInterfaces()中键入Type)
{
int len=type.GetInterfaces().Length;
如果(长度>最大值)
{
max=len;
结果:添加(类型);
}
}
如果(results.Count>0)
foreach(输入结果)
Console.WriteLine(type.FullName);
不可能简单地检索即时接口,但我们有必要的类型元数据来解决它
如果我们从整个继承链中有一个平坦的接口列表,并且每个接口都可以告诉我们它还实现/需要哪些同级接口(它们是这样做的),那么我们可以递归地删除父级上实现或需要的每个接口
这种方法有点过于激进,因为如果您在立即类上声明IFoo
和IBar
,并且IFoo
是IBar
所必需的,它将被删除(但实际上,这不仅仅是一种好奇心的练习吗?我不清楚它的实际用途……)
这段代码非常难看,但我只是把它放在一个新的/裸的MonoDevelop安装中
public static void Main (string[] args)
{
var nonInheritedInterfaces = typeof(Test).GetImmediateInterfaces();
foreach(var iface in nonInheritedInterfaces)
{
Console.WriteLine(iface);
}
Console.Read();
}
class Test : ITest { }
interface ITest : ITestParent { }
interface ITestParent { }
public static class TypeExtensions
{
public static Type[] GetImmediateInterfaces(this Type type)
{
var allInterfaces = type.GetInterfaces();
var nonInheritedInterfaces = new HashSet<Type>(allInterfaces);
foreach(var iface in allInterfaces)
{
RemoveInheritedInterfaces(iface, nonInheritedInterfaces);
}
return nonInheritedInterfaces.ToArray();
}
private static void RemoveInheritedInterfaces(Type iface, HashSet<Type> ifaces)
{
foreach(var inheritedIface in iface.GetInterfaces())
{
ifaces.Remove(inheritedIface);
RemoveInheritedInterfaces(inheritedIface, ifaces);
}
}
}
private static void RemoveInheritedInterfaces(Type iface, Dictionary<Type, Type> interfaces)
{
foreach(var inheritedInterface in iface.GetInterfaces())
{
interfaces.Remove(inheritedInterface);
RemoveInheritedInterfaces(inheritedInterface, interfaces);
}
}
publicstaticvoidmain(字符串[]args)
{
var nonheritedinterfaces=typeof(Test).GetImmediateInterfaces();
foreach(非继承接口中的变量)
{
控制台写入线(iface);
}
Console.Read();
}
类测试:ITest{}
接口ITest:ITestParent{}
接口ITestParent{}
公共静态类类型扩展
{
公共静态类型[]GetImmediateInterface(此类型)
{
var allInterfaces=type.GetInterfaces();
var nonheritedinterfaces=新哈希集(allInterfaces);
foreach(所有界面中的变量)
{
移除非继承性接口(iface,非继承性接口);
}
返回非heritedInterface.ToArray();
}
私有静态void RemoveInheritedInterfaces(类型iface,HashSet ifaces)
{
foreach(iface.GetInterfaces()中的var inheritedIface)
{
i.移除(面);
删除InheritedInterface(InheritedInterface,ifaces);
}
}
}
专用静态void RemoveInheritedInterfaces(iface类型,字典接口)
{
foreach(iface.GetInterfaces()中的var inheritedInterface)
{
接口。删除(继承接口);
移除inheritedInterface(继承的接口、接口);
}
}
您可以尝试以下方法:
Type[] allInterfaces = typeof(Test).GetInterfaces();
var exceptInheritedInterfaces = allInterfaces.Except(
allInterfaces.SelectMany(t => t.GetInterfaces())
);
public interface A : B
{
}
public interface B : C
{
}
public interface C
{
}
public interface D
{
}
public class MyType : A, D
{
}
所以,如果你有这样的东西:
Type[] allInterfaces = typeof(Test).GetInterfaces();
var exceptInheritedInterfaces = allInterfaces.Except(
allInterfaces.SelectMany(t => t.GetInterfaces())
);
public interface A : B
{
}
public interface B : C
{
}
public interface C
{
}
public interface D
{
}
public class MyType : A, D
{
}
代码将返回A和D如果是公共类测试:ITest,ITesting
?为什么要这样?因为我想知道类直接从哪些接口继承?而不是它间接继承的接口,以动态生成新类型。这和为什么重要吗?严格地说,您不继承接口,而是实现它们,因此类Test
在本例中提供了ITest
和ITesting
的实现。ITest
“继承”自ITest
,这一事实意味着任何实现ITest
的类型都必须提供
public static void Main (string[] args)
{
var nonInheritedInterfaces = typeof(Test).GetImmediateInterfaces();
foreach(var iface in nonInheritedInterfaces)
{
Console.WriteLine(iface);
}
Console.Read();
}
class Test : ITest { }
interface ITest : ITestParent { }
interface ITestParent { }
public static class TypeExtensions
{
public static Type[] GetImmediateInterfaces(this Type type)
{
var allInterfaces = type.GetInterfaces();
var nonInheritedInterfaces = new HashSet<Type>(allInterfaces);
foreach(var iface in allInterfaces)
{
RemoveInheritedInterfaces(iface, nonInheritedInterfaces);
}
return nonInheritedInterfaces.ToArray();
}
private static void RemoveInheritedInterfaces(Type iface, HashSet<Type> ifaces)
{
foreach(var inheritedIface in iface.GetInterfaces())
{
ifaces.Remove(inheritedIface);
RemoveInheritedInterfaces(inheritedIface, ifaces);
}
}
}
private static void RemoveInheritedInterfaces(Type iface, Dictionary<Type, Type> interfaces)
{
foreach(var inheritedInterface in iface.GetInterfaces())
{
interfaces.Remove(inheritedInterface);
RemoveInheritedInterfaces(inheritedInterface, interfaces);
}
}
Type[] allInterfaces = typeof(Test).GetInterfaces();
var exceptInheritedInterfaces = allInterfaces.Except(
allInterfaces.SelectMany(t => t.GetInterfaces())
);
public interface A : B
{
}
public interface B : C
{
}
public interface C
{
}
public interface D
{
}
public class MyType : A, D
{
}