При перечислении интерфейсов типа, как получить только те, которые наследуются напрямую? - PullRequest
2 голосов
/ 11 февраля 2009

Я не уверен в точной терминологии здесь. В принципе, если у меня есть модель, как:

class Student : IDoSchool {}
class Freshman : Student {}
interface IDoSchool {}

Какой код скажет мне, что Freshman напрямую не реализует никаких интерфейсов, а Student непосредственно реализует IDoSchool?

Другими словами (без учета плохой терминологии) я хочу что-то вроде этого:

typeof(Freshman).GetInterfaces(BindingFlags.DeclaredOnly); // nothing
typeof(Student).GetInterfaces(BindingFlags.DeclaredOnly); // IDoSchool

Мысли

Ответы [ 4 ]

1 голос
/ 11 февраля 2009

Я подозреваю, что семантика интерфейса не соответствует тому, что вы пытаетесь сделать.

Интерфейс просто говорит, что класс должен реализовать список членов. Класс наследует интерфейс, но дочерний класс по-прежнему несет ответственность за реализацию интерфейса, который он унаследовал от родителя. В большинстве случаев родительский объект уже предоставляет реализацию, поэтому мы склонны воспринимать реализацию интерфейса так же, как наследование, но на самом деле это совершенно разные концепции.

В вашем случае лучшее, что вы можете сделать, - это восстановить отображение интерфейса с помощью GetInterfaceMap () и убедиться, что вся реализация каждого элемента интерфейса идет от родителя, а не от дочернего элемента. Это лучшее, что вы можете сделать, но, тем не менее, он не будет делать то, что вы пытаетесь сделать.

Кроме того, возможно ли в вашем случае использовать полностью абстрактные классы вместо интерфейсов? Вы не можете использовать множественное наследование, но, возможно, все ваши правила подразумевают очень линейное наследование?

0 голосов
/ 11 февраля 2009
 typeof("the object").GetInterfaces().Count==0
0 голосов
/ 11 февраля 2009

Извините, что опубликовал это как ответ, на самом деле это скорее мысль и предложение, но это не вписалось бы в комментарий ...

Что делать, если у вас следующая ситуация:

interface IA{
    void foo();
}
class CA : IA{
    public void foo(){
        Console.Writeline("Class A");
    }
}
class CB : CA, IA{
    public new void foo(){
        Console.Writeline("Class B");
    }
}

Я полагаю, что CB должен возвращать IA среди «непосредственно реализованных интерфейсов», но если вы сравните CB с CA, вы увидите, что они реализуют одинаковые интерфейсы, поэтому подход поиска различий не будет работать.
Прежде чем сходить с ума в поисках решения, пытались ли вы взглянуть на MSIL или код, декомпилированный из Reflector, чтобы узнать, возможно ли это вообще?

0 голосов
/ 11 февраля 2009

Просто идея ...

Вы можете получить интерфейсы класса и интерфейсы базового класса. Тогда получите разницу.

EDIT:

Я проверил идею, работает:

public static Type[] GetDirectInterfaces(Type type)
{
    if (type.BaseType == null)
        return type.GetInterfaces();
    Type[] BaseInterfaces = type.BaseType.GetInterfaces();
    Type[] ThisInferfaces = type.GetInterfaces();
    return ThisInferfaces.Except(BaseInterfaces).ToArray();
}

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

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