假设我有一个接口的继承树:
IParent> IChild> IGrandChild
我将如何:
例如:
var myClass = FindImplementor<IParent>();
var myInterface = ClosestAncestor<IParent, myclass>();
我不打算创建与上述签名相匹配的功能。这只是为了澄清。
IParent的后代以及实现类都在动态加载的程序集中。我不确定这是否会有所作为。
答案 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的答案)