Ist es möglich, alle Nachkommen eines Typs transitiv zu finden, einschließlich Implementierungen eines generischen Typs?C#

Ein Treffpunkt für C#-Programmierer
Guest
 Ist es möglich, alle Nachkommen eines Typs transitiv zu finden, einschließlich Implementierungen eines generischen Typs?

Post by Guest »

Bevor Sie für das Schließen als Duplikat stimmen, lesen Sie bitte sorgfältig die Beschreibung des Problems.
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

A
,

Code: Select all

B
[/b], B] für seine übergeordneten Typen und [

Code: Select all

D
[/b], D, E] für abgeleitete Typen. Obwohl diese Hierarchie streng vertikal ist, sollten die abgeleiteten Typen alle untergeordneten Typen transitiv einschließen.
Ich 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

A
, B] und [

Code: Select all

D
, E].
Der 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);
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post