2009-11-12 59 views
0

可以说我有接口的一个继承树:确定孩子最接近接口类

IParent> ICHILD> IGrandChild

我怎么会:

  1. 找到实现IParent
  2. 确定也是IParent子项的类的最近祖先。

例如:

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

我不希望创建符合上述特征,其功能。这只是为了澄清。

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

+0

C#支持接口的多重继承。假设有两个从IParent继承的接口:IChild1和IChild2。如果一个类实现IChild1和IChild2,会发生什么? – 2009-11-12 15:55:47

+0

旧的多重继承钻石。在我的情况下,我没有使用该功能。我实现多个接口的所有类都实现了没有共同祖先的接口。 – 2009-11-12 16:01:25

+0

即使没有“钻石”,您仍然必须遍历整个接口继承树,才能找到IParent。递归函数让人想起遍历树来寻找某物。 – 2009-11-12 16:19:42

回答

1

您可以使用作为关键字并检查为空。

例子:

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

要获得IParent

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

有没有简单和完美的工作方式得到"closest ancestors" of an interface

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

如可以看出,该代码假定类实现IParent(否则 - 错误...)。

试验样品:

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

我假定该组件被加载到应用程序域和码搜索一个实施者的地方。如果只有单个程序集很有趣,那么你只能得到这个程序集类型(就像在Guillaume的答案中一样)

+0

当Type和BaseType都实现IParent接口时,您的最靠近的祖先将失败。 – Guillaume 2009-11-16 08:32:54

+0

@Guillaume,你是对的,这是一个错误:) – Elisha 2009-11-16 18:40:13