Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否仅查找非继承接口?_C#_.net_Reflection_.net 4.0_Interface - Fatal编程技术网

C# 是否仅查找非继承接口?

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

我试图通过反射对类的接口执行查询,但是方法Type.GetInterfaces()也返回所有继承的接口

代码

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
{
}

代码将返回AD

如果是
公共类测试: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
{
}