Пожалуйста, прежде чем голосовать за закрытие как дубликат, внимательно прочитайте описание проблемы.
Для данного типа класса мне нужно обнаружить его полную иерархию, включая как базовые, так и производные классы. . Единственное требование, которое сбивает с толку, — это включение открытых универсальных типов в результирующий набор в любом направлении.
При наличии такого набора классов, как класс A , B: A, C: B и D: C, E: D, результат гипотетического DiscoverTypeTree(typeof(C)) — это [A, B, B] для родительских типов и [D, D, E] для производных типов. Хотя эта иерархия строго вертикальна, производные типы должны транзитивно включать все дочерние типы.
Я застрял в том, что не могу найти способ последовательно включать открытые универсальные типы. в выводе вместе с их конкретными версиями. В разных итерациях мне либо не удавалось обнаружить все производные типы, когда использовались открытые дженерики, либо я включал в результат только конкретные типы, пропуская открытые дженерики, либо возникали другие проблемы с отсутствующими типами. Теперь я застрял в проблеме «включать только конкретные типы, пропуская в результате открытые дженерики». Таким образом, для приведенного выше примера неправильный результат — это [A, B] и [D, E].
Код (языковая версия — 13, я нацелен на .NET 8; он написан как локальная функция):
var hierarchies = new Dictionary();
var derivedTypes = new Dictionary();
void discoverHierarchy()
where T : class {
void _discover(Type type) {
if (!hierarchies.ContainsKey(type)) {
var hierarchy = new LinkedList();
hierarchies.Add(type, hierarchy);
var t2 = type;
do {
_ = hierarchy.AddFirst(t2);
_discover(t2);
t2 = t2.BaseType;
}
while (t2 is not null && t2 != typeof(object));
var derived = new List();
var def = type.IsGenericTypeDefinition ? type : null;
if (def is not null && def != type) {
_discover(def);
}
foreach (var t in assemblyTypes) // Cached output of `assembly.GetTypes()`.
{
if (t.IsSubclassOf(type)) {
derived.Add(t);
_discover(t);
} else {
var t3 = t;
var list3 = new List();
do {
list3.Add(t3);
if (t3.BaseType?.IsGenericType is true && t3.BaseType.GetGenericTypeDefinition() == def) {
derived.AddRange(list3);
foreach (var _t3 in list3) {
_discover(_t3);
}
break;
} else {
t3 = t3.BaseType;
}
}
while (t3 is not null);
}
}
_ = derivedTypes.TryAdd(type, []);
derivedTypes[type].AddRange(derived);
}
};
var type = typeof(T);
_discover(type);
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ng-impleme
Можно ли транзитивно найти всех потомков типа, включая реализации универсального типа? ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Можно ли транзитивно найти всех потомков типа, включая реализации универсального типа?
Anonymous » » в форуме C# - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли транзитивно найти всех потомков типа, включая реализации универсального типа?
Anonymous » » в форуме C# - 0 Ответы
- 14 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли транзитивно найти всех потомков типа, включая реализации универсального типа?
Anonymous » » в форуме C# - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Можно ли транзитивно найти всех потомков типа, включая реализации универсального типа?
Anonymous » » в форуме C# - 0 Ответы
- 35 Просмотры
-
Последнее сообщение Anonymous
-