Определение дочернего интерфейса, ближайшего к классу - PullRequest
1 голос
/ 12 ноября 2009

Допустим, у меня есть дерево наследования интерфейсов:

IParent> IChild> IGrandChild

Как бы я:

  1. Найдите класс, который реализует IParent
  2. Определите ближайшего предка класса, который также является потомком IParent.

Например:

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

Я не собираюсь создавать функции, которые соответствуют вышеуказанным сигнатурам. Это было только для пояснения.

Потомки IParent и класса реализации находятся в динамически загружаемой сборке. Я не уверен, будет ли это иметь значение или нет.

Ответы [ 3 ]

1 голос
/ 12 ноября 2009

Получить "Реализаторы" IParent

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

Не существует простого и идеально работающего способа получить «ближайших предков» интерфейса .

1 голос
/ 12 ноября 2009

Вы можете использовать в качестве ключевого слова и проверить на ноль.

Пример:

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

На самом деле мне не очень нравится идея, но это то, что пришло в голову. Есть ряд проблем с попыткой идентифицировать цепочку. На ум приходит несколько цепочек реализации.

0 голосов
/ 12 ноября 2009

Надеюсь, я правильно понял вопрос:)

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 (в противном случае - ошибка ...).

Тестовый образец:

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

Я предположил, что сборка загружена в домен приложения, и код выполняет поиск разработчика по всему миру. Если интересна только одна сборка, вы можете получить только эти типы сборок (как в ответе Гийома)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...