确定最接近类的子接口

时间:2009-11-12 15:51:40

标签: c# algorithm reflection inheritance interface

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

IParent> IChild> IGrandChild

我将如何:

  1. 找一个实现IParent
  2. 的类
  3. 确定类的最近祖先,也是IParent的子级。
  4. 例如:

    var myClass = FindImplementor<IParent>();
    var myInterface = ClosestAncestor<IParent, myclass>();
    

    我不打算创建与上述签名相匹配的功能。这只是为了澄清。

    IParent的后代以及实现类都在动态加载的程序集中。我不确定这是否会有所作为。

3 个答案:

答案 0 :(得分:1)

您可以使用 as 关键字并检查null。

示例:

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
实际上,我并不是真的喜欢这个主意,但这是我想到的。尝试识别链条存在许多问题。我想到了多个实施链。

答案 1 :(得分:1)

获得IParent

的“实施者”
var classes = Assembly.GetTypes();
var parentImplementors = classes.Where(x => x.IsAssignableFrom(typeof(IParent)));

获取"closest ancestors" of an interface没有简单而完美的工作方式。

答案 2 :(得分:0)

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

<强> 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);
}

可以看出,代码假定Class实现了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);
}

<强> FindImplementor

加载实现接口的第一个类型:

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

我假设程序集已加载到App Domain,代码会在整个地方搜索实现者。如果只有单个程序集很有意思,那么只能获得这种程序集类型(如Guillaume的答案)