Determining child interface closest to a class
Lets say I have a inheritance tree of interfaces:
IParent > IChild > IGrandChild
How would I:
- Find a class that implements IParent
- Determine the clos开发者_Python百科est ancestor of the class that is also a child of IParent.
For example:
var myClass = FindImplementor<IParent>();
var myInterface = ClosestAncestor<IParent, myclass>();
I'm not looking to create functions that match the above signatures. That was just for clarification.
The descendants of IParent as well as the implementation class are in a dynamically loaded assembly. I'm not sure if that would make a difference or not.
You can use the as keyword and check for null.
Example:
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
I'm not really liking the idea, actually, but it's what came to mind. There are a number of issues with trying to identify the chain. Multiple implementation chains come to mind.
To get "Implementors" of IParent
var classes = Assembly.GetTypes();
var parentImplementors = classes.Where(x => x.IsAssignableFrom(typeof(IParent)));
There is no simple and perfectly working way to get the "closest ancestors" of an interface.
I hope I understood the question correctly :)
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);
}
As it can be seen, the code assumes Class implements IParent (otherwise - bug...).
Test sample:
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
Loading first type that implements an interface:
public Type FindImplementor<T>()
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.FirstOrDefault(type => type.GetInterfaces().Contains(typeof(T)));
}
I assumed the assembly is loaded to the App Domain and the code searches all over the place for an implementer. If only single assembly is interesting, you can get only this assembly types (Like in Guillaume's answer)
精彩评论