2016-06-01 19 views
4

Ich habe einen Typ, der Generics verwendet. Nennen wir es FlowerDescriptor<T> sind einige Blumen beschrieben Nummern usw.Abgeleitete Typen und Generics

mit anderen Saiten

so FlowerDescriptor<int>;FlowerDescriptor<string>; etc

Ich möchte einen Mechanismus (wahrscheinlich Methoden Erweiterung) zu tun 2 Dinge

  • zu sehen, wenn etwas ist ein FlowerDescriptor und
  • zu sehen, was der Deskriptor ist.

I.e.

  • FlowerDescriptor<string>.GetType().IsFlowerDescriptor == true string.GetType().IsFlowerDescriptor == false.

ebenso könnte ich von FlowerDescriptor<int> d.h. herzuleiten class NumberedFlower: FlowerDescriptor<int>

neue NumberedFlower.GetType() IsFlowerDesriptor == true.

  • wie oben, aber gibt den Typ FlowerDescriptor<string>.GetType().GetFlowerDescriptor() == typeof(string) FlowerDescriptor<int>.GetType().GetFlowerDescriptor() == typeof(int) new NumberedFlower.GetType().GetFlowerDescriptor() == typeof(int)

Ich habe über mit Variationen von IsAssignableFrom gespielt und es fühlt sich an wie das sollte mit typeof(FlowerDescriptor<>).IsAssignableFrom(typeof(FlowerDescriptor<string>))

arbeiten, aber es funktioniert nicht. Wenn es jedoch den generischen Typ hinzufügt, tut es das.

Ich suche derzeit nach GetInterfaces, um verfügbare Schnittstellen zu kennen. Es wäre großartig, wirklich zu verstehen, was ich falsch zu tue ..

Antwort

4

Sofern Sie Schnittstellen in die Mischung hinzufügen möchten, ist die einzige Wahl, die Sie haben, ist zu

  1. erkennen, dass der Typ tatsächlich ein FlowerDescriptor<T>
  2. oder erkennen, dass die Art von etwas erbt, die ein FlowerDescriptor<T> ist

Leider glaube ich nicht, können Sie IsAssignableFrom verwenden, wenn es co mes, um generics zu öffnen, was bedeutet, dass wir die Erbkette bis zu den Basisklassen laufen lassen müssen. Hier

ist ein Beispiel Stück Code, das Richtige tun würde:

public static bool IsFlowerDescriptor(this Type type) 
{ 
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(FlowerDescriptor<>)) 
     return true; 
    if (type.BaseType != null) 
     return type.BaseType.IsFlowerDescriptor(); 

    return false; 
} 

hier ein .NET Fiddle Sie experimentieren können.

+0

Das sieht am nächsten .. Würde das funktionieren, wenn FlowerDescriptor nicht der Basistyp und/oder nicht der sofort abgeleitete Typ wäre? d. h. kann es den Baum gehen und ihn irgendwo dort finden. –

+0

Auch Schnittstellen im Mix? Wie so .. in der Produktion wäre es IFlowerDescriptor

2

Ich würde nicht erwarten, dass die Zeichenfolge oder int-Klasse wissen, ob es ein Deskriptor ist, es macht viel mehr Sinn, diese Informationen aus dem FlowerDescriptor zu erhalten.

Dass gesagt wird, wenn Sie Reflektion verwenden möchten Sie die generische Typdefinition aus der FlowerDescriptor Instanz bekommen konnte

FlowerDescriptor<int> f = new FlowerDescriptor<int>(); 
Type t = f.GetType(); 
Type[] typeArguments = t.GetGenericArguments(); 
//check if type you care about is in typeArguments 
0

Hier ist, wie Sie diese beiden Werte erhalten würden:

bool isFlowerDescriptor = x is FlowerDescriptor<object>; 

Type descriptorType = x.GetType().GetGenericArguments()[0]; 

Sie könnten wrap diese in Erweiterungsmethoden, wenn Sie möchten. Fügen Sie null-checks usw. hinzu.

0

Sie könnten eine nicht-generische Basisklasse in Erwägung ziehen. Dann könnte Ihre Struktur wie folgt aussehen:

public abstract class FlowerDescriptor { } 

public class FlowerDescriptor<T> : FlowerDescriptor { } 

public class NumberedFlower : FlowerDescriptor<int> { } 

Ihre 2 Erweiterungen wäre:

public static class Extensions 
{ 
    public static bool IsFlowerDescriptor(this object o) 
    { 
     return o is FlowerDescriptor; 
    } 

    public static Type GetFlowerDescriptor<T>(this FlowerDescriptor<T> o) 
    { 
     return typeof (T); 
    } 
} 

und Sie würden verwenden Sie es mögen:

public static void Main() 
{ 
    Console.WriteLine(new NumberedFlower().IsFlowerDescriptor()); //true 
    Console.WriteLine(new NumberedFlower().GetFlowerDescriptor()); //System.Int32 
} 

Generics haben negative Auswirkungen, wenn es darum geht, Überdenken und Vergleichen von Typen, weil ein FlowerDescriptor<int> ein anderer Typ als FlowerDescriptor<string> ist. Dafür habe ich keinen guten Rhythmus gefunden.

+0

Danke - aber ich möchte die Implementierung nicht ändern, um dieser Anforderung zu entsprechen. –

Verwandte Themen