C# 确定最接近类的子接口
假设我有一个接口的继承树: iPart>IChild>IGrandChild 我将如何: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
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将失败。