Почему GetInheritedTypes (typeof (C)) возвращает 0 элементов вместо Typeof (TreeNode)?
Потому что TreeNode
нет в той же сборке, что и C
. Ваш запрос «из всех типов в той же сборке, что и C, дает мне те, которые C присваивается».
Я подозреваю, однако, что фактическая проблема заключается в:
Как перечислить все базовые типы данного типа?
Вы делаете не сделать поиск по всем типам в сборке и проверить, какие из них являются назначаемыми. Это похоже на попытку выяснить, кто твоя мама, спрашивая каждого человека в вашем городе: «Ты мать Джека?» вместо того, чтобы спросить Джека «кто твоя мама?».
Нечто подобное было бы намного лучше:
public static IEnumerable<Type> BaseTypes(this Type type)
{
if (type == null) throw new ArgumentNullException("type");
Type baseType = type;
while(true)
{
baseType = baseType.BaseType;
if (baseType == null)
break;
yield return baseType;
}
}
Комментатор спрашивает
что, если вы хотите, чтобы получить все реализованные интерфейсы?
Звоните GetInterfaces()
на тип объекта.
(ранняя версия этого поста предложил получать транзитивное замыкание интерфейсов, я совсем забыл, что GetInterfaces
уже делает это.)
Как еще был мой исходный код сломана?
Ну, предположим, например, у вас есть тип
class D<T> {}
и класс
class E : D<int> {}
Теперь вы спросите «дали E
, перечислить все типы X
в сборке, так что значение типа E
может быть присвоено переменной типа X
". Ну, D<T>
находится в сборке; есть D<T>
такой тип? №. E
присваивается переменной типа D<int>
, а не переменной типа D<T>
.
Отношение «присваиваемые» и отношения «наследует от» имеют довольно много перекрытий, но они совсем не относятся к отношениям, поэтому не делайте вид, что они есть.
Являются ли 'C' и' TreeNode' объявленными в той же сборке? – MarcinJuraszek
Почему вы не просто используете 'type.BaseType'? Это даст вам базовый тип типа без перечисления каждого типа в сборке. – Jamiec
@MarcinJuraszek: Нет, это не так, если Джек не работает над добавлением типа C в System.Windows.Forms.DLL. –