检查类型是否直接实现接口。并非来自继承

Pan*_*321 1 c# inheritance interface

从类型 A、B、C、ANotState、BNotState 列表中,我想获取标有接口的 A、B、C。但是,如果确实从 ANotState 或 BNotState 获取接口,我只能得到从 C 继承的 isState(在 BNotState 情况下从 ANotState 继承)。

有没有办法知道接口是否是直接实现的?

public class Program
{
    public static void Main()
    {
        List<Type> types = new List<Type>{typeof(A), typeof(B), typeof(C), typeof(ANotState), typeof(BNotState)};
        
        //Now remove from list types that are not implementing isState interface directly which means ANotState and BNotState
    }
}

public interface isState{}


public class A : isState
{
    
}

public abstract class B : A, isState
{

}

public abstract class C : B, isState
{

}

public class ANotState : C
{

}

public class BNotState : ANotState
{

}
Run Code Online (Sandbox Code Playgroud)

Ond*_*cny 6

有一个解决方案部分有效。您可以检索当前类型实现的接口,然后检索其父类型实现的接口,然后减去这两个集合。像这样:

public HashSet<Type> GetDirectlyImplementedInterfaces<T>()
{
    // interfaces of the given type T
    var allIfaces = typeof(T).GetInterfaces().ToHashSet();
    
    // interfaces of its base type
    var baseIfaces = typeof(T).BaseType.GetInterfaces().ToHashSet();
    
    // subtract
    allIfaces.ExceptWith(baseIfaces);
    return allIfaces;
}
Run Code Online (Sandbox Code Playgroud)

但是,它仅适用于在继承层次结构中第一次指定给定接口。例如,在您的情况下,A上面的方法 returns isState,但对于两者,它BC 没有,因为接口首先由其父类型实现,即A

因此,我建议不要使用标记接口,而是通过不可继承的自定义属性指定相同的信息:

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class IsStateAttribute : Attribute { }
Run Code Online (Sandbox Code Playgroud)

然后你可以使用这样的方法来检查类型T是否代表状态:

public bool CheckIsState<T>()
{
    return typeof(T).GetCustomAttribute<IsStateAttribute>() != null;
}
Run Code Online (Sandbox Code Playgroud)

该解决方案正确地将AB和识别C为状态,并将ANotStateBNotState识别为非状态。

如果您需要在状态接口中声明一些成员,只需结合使用这两种方法即可。