Прежде всего, есть много вопросов, подобных этому, и, возможно, некоторые ОП даже задавали этот же вопрос. Проблема в том, что ни один ответ на эти вопросы (принятый или нет) на самом деле не отвечает на этот вопрос, по крайней мере, ни один, который я могу найти.
Как я могу определить интерфейсы, которые класс объявляет напрямую, а не те, которые наследуются ни родителями, ни объявленными интерфейсами?
, например
interface I {}
interface W : I {}
class C : W {}
class D : C, I {}
class E : D {}
Результаты:
C
объявляет W
D
объявляет I
E
не объявляет
Приемлемое решение может потребовать, чтобы интерфейсы имели хотя бы один метод.
Если вы считаете, что это действительно невозможно, будьте осторожны, чтобы не совершить эту ошибку, которую на самом деле можно сделать.
InterfaceMap
обрабатывает много случаев, но не все (я привожу пример ниже, не разрешимый InterfaceMap
). У меня была одна идея, но я не знаю, как ее реализовать, - декомпилировать байт-код класса и посмотреть, что объявлено, поскольку такие инструменты, как ILSpy, правильно идентифицируют каждый случай! Если вам нравится эта идея, пожалуйста, дайте мне ссылку на дополнительную информацию в этой области.
Я ожидаю, что некоторые из вас посоветуют мне очистить мой дизайн. Если это не ваш аргумент, остальная часть поста не имеет отношения к вам.
Часть цели моего проекта заключается в отслеживании потенциальных путей кода данных типов (во время выполнения). Чтобы программно определить, какой метод будет вызываться для целевого типа, без фактического вызова метода или создания экземпляра целевого типа, необходимо знать объявленные интерфейсы целевого типа, чтобы детерминистически решить эту проблему. «Нет», вы говорите? Рассмотрим:
interface I { int Foo(); }
class C : I { public int Foo() { return 1; } }
class D : C { public new int Foo() { return 2; } }
class E : D, I { }
C p = new E();
Assert.AreEqual(1 or 2, (p as I).Foo())
Правильный ответ 2
, но если вы измените объявление E
, чтобы оно не включало I
напрямую, ответ будет 1
. Теперь, конечно, это крайний случай, но это также правильный ответ. Поэтому мой движок не полностью совместим с потенциальным кодом пользователя. Попросить пользователей очистить свой код, чтобы использовать мой инструмент, недопустимо. (Обратите внимание, что существуют десятки более интересных правил приведения к интерфейсу, но я не буду их здесь обсуждать).