【问题标题】:Determining child interface closest to a class确定最接近类的子接口
【发布时间】:2010-12-15 22:41:11
【问题描述】:

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

IParent > IChild > IGrandChild

我会怎么做:

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

例如:

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

我不希望创建与上述签名匹配的函数。这只是为了澄清。

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

【问题讨论】:

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

标签: c# algorithm reflection inheritance interface


【解决方案1】:

您可以使用 as 关键字并检查是否为空。

例子:

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

实际上,我并不是很喜欢这个想法,但它就是我想到的。尝试识别链条存在许多问题。我想到了多个实现链。

【讨论】:

    【解决方案2】:

    获取IParent的“实施者”

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

    没有简单而完美的方法来获取"closest ancestors" of an interface

    【讨论】:

      【解决方案3】:

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

      最近的祖先

      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(否则 - 错误...)。

      测试样本:

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

      查找实施者

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

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

      我假设程序集已加载到应用程序域,并且代码到处搜索实现者。如果只有单个程序集很有趣,您只能获得这种程序集类型(就像纪尧姆的回答一样)

      【讨论】:

      • 当 Type 和 BaseType 都实现 IParent 接口时,你的 ClosestAncestor 将失败。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2016-04-08
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多