Bei einem gegebenen Klassentyp muss ich seine vollständige Hierarchie ermitteln, einschließlich der Basis- und abgeleiteten Klassen . Die einzige Anforderung, die einen Schraubenschlüssel ins Wanken bringt, ist, dass offene generische Typen in beide Richtungen in die Ergebnismenge einbezogen werden müssen.
Gegeben ist eine Menge von Klassen wie Klasse A , B: A, C: B und D: C, E: D, das Ergebnis der Hypothese DiscoverTypeTree(typeof(C)) ist [
Code: Select all
ACode: Select all
BCode: Select all
DIch stecke nicht fest, weil ich anscheinend keine Möglichkeit finde, die offenen generischen Typen konsistent einzubeziehen in der Ausgabe zusammen mit ihren konkreten Versionen. In verschiedenen Iterationen konnte ich entweder nicht alle abgeleiteten Typen erkennen, wenn offene Generika involviert waren, oder ich habe nur die konkreten Typen einbezogen und die offenen Generika im Ergebnis übersprungen, oder es gab andere Probleme mit fehlenden Typen. Ich stecke jetzt mit dem Problem fest, dass nur die konkreten Typen einbezogen werden und die offenen Generika im Ergebnis übersprungen werden. Für das obige Beispiel ist das falsche Ergebnis also das von [
Code: Select all
ACode: Select all
DDer Code (die Sprachversion ist 13 und ich ziele auf .NET 8; dies ist als lokale Funktion geschrieben):
Code: Select all
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);
}
 Mobile version
 Mobile version