如何枚举在继承类上直接定义的接口列表?

Jor*_*dan 8 c# reflection interface class

更新的问题给出了Andrew Hare的正确答案:

鉴于以下C#类:

public class Bar : Foo, IDisposable
{
    // implementation of Bar and IDisposable
}

public class Foo : IEnumerable<int>
{
    // implementation of Foo and all its inherited interfaces
}
Run Code Online (Sandbox Code Playgroud)

我想要一个类似下面的方法,它不会在断言上失败(注意:你不能改变断言):

public void SomeMethod()
{
   // This doesn't work
   Type[] interfaces = typeof(Bar).GetInterfaces();

   Debug.Assert(interfaces != null);
   Debug.Assert(interfaces.Length == 1);
   Debug.Assert(interfaces[0] == typeof(IDisposable));
}
Run Code Online (Sandbox Code Playgroud)

有人可以通过修复此方法来帮助断言不会失败吗?

呼叫typeof(Bar).GetInterfaces()不起作用,因为它返回的整个界面的层次结构(即interfaces变量包含IEnumerable<int>,IEnumerableIDisposable),而不仅仅是顶层.

Che*_*eso 8

试试这个:

using System.Linq;    
public static class Extensions
{
    public static Type[] GetTopLevelInterfaces(this Type t)
    {
        Type[] allInterfaces = t.GetInterfaces();
        var selection = allInterfaces
            .Where(x => !allInterfaces.Any(y => y.GetInterfaces().Contains(x)))
            .Except(t.BaseType.GetInterfaces());
        return selection.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

    private void Check(Type t, Type i)
    {
        var interfaces = t.GetTopLevelInterfaces();

        Debug.Assert(interfaces != null, "interfaces is null");
        Debug.Assert(interfaces.Length == 1, "length is not 1");
        Debug.Assert(interfaces[0] == i, "the expected interface was not found");

        System.Console.WriteLine("\n{0}", t.ToString());
        foreach (var intf in  interfaces)
            System.Console.WriteLine("  " + intf.ToString());

    }

    public void Run()
    {
        Check(typeof(Foo), typeof(IEnumerable<int>));
        Check(typeof(Bar), typeof(IDisposable));
    }
Run Code Online (Sandbox Code Playgroud)

如其他地方所述,这仅在checked类型显式实现单个接口时才有效.如果您有多个,则需要更改断言.