C# 确定最接近类的子接口

C# 确定最接近类的子接口,c#,algorithm,reflection,inheritance,interface,C#,Algorithm,Reflection,Inheritance,Interface,假设我有一个接口的继承树: iPart>IChild>IGrandChild 我将如何: 查找实现IParent的类 确定类的最近祖先,该类也是IParent的子类 例如: var myClass = FindImplementor<IParent>(); var myInterface = ClosestAncestor<IParent, myclass>(); var myClass=FindImplementor(); var myInterface=Closes

假设我有一个接口的继承树:

iPart>IChild>IGrandChild

我将如何:

  • 查找实现IParent的类
  • 确定类的最近祖先,该类也是IParent的子类
  • 例如:

    var myClass = FindImplementor<IParent>();
    var myInterface = ClosestAncestor<IParent, myclass>();
    
    var myClass=FindImplementor();
    var myInterface=ClosestAncestor();
    
    我不想创建与上述签名匹配的函数。这只是为了澄清


    IParent的子体以及实现类都位于动态加载的程序集中。我不确定这是否会产生影响。

    您可以将用作关键字并检查空值

    例如:

    var someObject = GetMeSomething();  //returns some IParent/IChild/IGrandChild
    
    if ((someObject as IParent) != null)
        if ((someObject as IChild) != null)
        {
            if ((someObject as IGrandChild) != null)
            {
                //you have an IGrandChild
            }
            else
            {
                //you have an IChild
            }
        }
        else
        {
            //you have an IParent
        }
    }
    //you have something other than your interface hierarchy
    
    事实上,我并不真的喜欢这个主意,但这正是我想到的。试图识别链条存在许多问题。我想到了多个实施链。

    以获得IParent的“实施者”

    var classes = Assembly.GetTypes();
    var parentImplementors = classes.Where(x => x.IsAssignableFrom(typeof(IParent)));
    

    没有一种简单而完美的方法可以解决这个问题。

    我希望我正确地理解了这个问题:)

    ClosestAncestor

    public Type ClosestAncestor<IParent, Class>()
    {
        return ClosestAncestor<IParent>(typeof(Class));
    }
    
    public Type ClosestAncestor<IParent>(Type typeOfClass)
    {
        var baseType = typeOfClass.BaseType;
        if(typeOfClass.GetInterfaces().Contains(typeof(IParent)) &&
            ! baseType.GetInterfaces().Contains(typeof(IParent)))
        {
            return typeOfClass;
        }
    
        return ClosestAncestor<IParent>(baseType);
    }
    
    public类型ClosestAncestor()
    {
    返回关闭状态器(类型(类));
    }
    公共类型关闭器(类的类型)
    {
    var baseType=typeOfClass.baseType;
    if(typeOfClass.GetInterfaces()包含(typeof(IParent))&&
    !baseType.GetInterfaces()包含(typeof(IParent)))
    {
    类的返回类型;
    }
    返回闭合器(基本型);
    }
    
    可以看出,代码假定类实现了IParent(否则-bug…)

    测试样本:

    public interface I {}
    public class A {}
    public class B : A, I {}
    public class C : B {}
    
    [Test]
    public void ClosestAncestorTest()
    {
        Type closestAncestor = ClosestAncestor<I,C>();
        Assert.AreEqual(typeof(B), closestAncestor);
    }
    
    公共接口I{}
    公共A类{}
    公共B类:A,I{}
    公共类C:B{}
    [测试]
    公共无效关闭状态侵权测试()
    {
    键入closestAncestor=closestAncestor();
    Assert.AreEqual(类型(B),closestAncestor);
    }
    
    FindImplementor

    public Type ClosestAncestor<IParent, Class>()
    {
        return ClosestAncestor<IParent>(typeof(Class));
    }
    
    public Type ClosestAncestor<IParent>(Type typeOfClass)
    {
        var baseType = typeOfClass.BaseType;
        if(typeOfClass.GetInterfaces().Contains(typeof(IParent)) &&
            ! baseType.GetInterfaces().Contains(typeof(IParent)))
        {
            return typeOfClass;
        }
    
        return ClosestAncestor<IParent>(baseType);
    }
    
    正在加载实现接口的第一种类型:

    public Type FindImplementor<T>()
    {
        return AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(assembly => assembly.GetTypes())
            .FirstOrDefault(type => type.GetInterfaces().Contains(typeof(T)));
    }
    
    public类型FindImplementor()
    {
    返回AppDomain.CurrentDomain.GetAssemblys()
    .SelectMany(assembly=>assembly.GetTypes())
    .FirstOrDefault(type=>type.GetInterfaces().Contains(typeof(T)));
    }
    

    我假设程序集已加载到应用程序域,代码会到处搜索实现者。如果只对单个程序集感兴趣,那么您只能得到这种程序集类型(如Guillaume的回答)

    C#支持接口的多重继承。假设有两个intefaces继承自iPart:IChild1和IChild2。如果一个类同时实现了IChild1和IChild2,会发生什么?旧的多重继承菱形。在我的场景中,我没有使用该功能。我所有实现多个接口的类都实现了没有共同祖先的接口。即使没有“钻石”,您仍然需要遍历整个接口继承树才能找到IParent。递归函数会遍历一棵树来找到一些东西。当Type和BaseType都实现IParent接口时,ClosestAncestor将失败。