2015-02-24 3 views
13

Ich mache ein großes bisschen Reflexion in meinem aktuellen Projekt, und ich versuche, ein paar Hilfsmethoden zur Verfügung zu stellen, nur um alles in Ordnung zu halten.Überprüfen, ob Type oder Instanz implementiert IEnumerable unabhängig von Typ T

Ich möchte ein Paar von Methoden zur Verfügung zu stellen, um zu bestimmen, ob ein Typ oder Instanz IEnumerable implementiert - unabhängig von der Art T. Hier ist, was ich im Moment haben:

public static bool IsEnumerable(this Type type) 
{ 
    return (type is IEnumerable); 
} 

public static bool IsEnumerable(this object obj) 
{ 
    return (obj as IEnumerable != null); 
} 

Als ich sie testen Verwendung:

Debug.WriteLine("Type IEnumerable: " + typeof(IEnumerable).IsEnumerable()); 
Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable()); 
Debug.WriteLine("Type List:   " + typeof(List<string>).IsEnumerable()); 
Debug.WriteLine("Type string:  " + typeof(string).IsEnumerable()); 
Debug.WriteLine("Type DateTime:  " + typeof(DateTime).IsEnumerable()); 
Debug.WriteLine("Instance List:  " + new List<string>().IsEnumerable()); 
Debug.WriteLine("Instance string: " + "".IsEnumerable()); 
Debug.WriteLine("Instance DateTime: " + new DateTime().IsEnumerable()); 

ich dies als das Ergebnis:

Type IEnumerable: False 
Type IEnumerable<>: False 
Type List:   False 
Type string:  False 
Type DateTime:  False 
Instance List:  True 
Instance string: True 
Instance DateTime: False 

die Art Methode tun Es scheint überhaupt nicht zu funktionieren - ich hatte zumindest für das direkte System.Collections.IEnumerable Match ein echtes Match erwartet.

Ich bin mir bewusst, dass String technisch aufzählbar ist, wenn auch mit ein paar Einschränkungen. Idealerweise würde ich in diesem Fall jedoch die Hilfsmethode benötigen, um dafür false zurückzugeben. Ich brauche nur die Instanzen mit einem definierten IEnumerable<T> Typ, um wahr zurückzugeben.

Ich habe wahrscheinlich gerade etwas ziemlich offensichtlich verpasst - kann mir jemand in die richtige Richtung zeigen?

+0

Ich verstehe die Frage nicht. Es ist klar, warum 'typeof()' jeder Typ nicht 'wahr' zurückgibt; Sie fragen, ob das _type object_ die Schnittstelle implementiert, nicht den Typ selbst. Vielleicht willst du 'IsAssignableFrom()'? Aber auf welche Weise denkst du, dass "String" sich nicht qualifiziert? Es hat "einen definierten IEnumerable ' type ". –

+0

Ja, das war das Problem mit dem Typ Eins - ich habe mir die Nester der Reflexion angesehen, die den ganzen Tag zwischen Typen und Instanzen sprangen, und wurde mehr als ein bisschen verwirrt! "string" qualifiziert sich, aber in diesem Fall muss ich es wirklich ausschließen - es ist wahrscheinlich eher eine Frage der Methodenbenennung in diesem Stadium. Ich denke, ich lasse das so, wie es ist, und füge ein weiteres hinzu, das zuerst die Zeichenfolgen zuerst eintippt. – Octopoid

+0

Stimmen Sie mit @JeroenMostert überein ... das "Duplikat" fragt, ob ein Typ 'IEnumerable 'mit Reflektion implementiert, dieser fragt, ob ein Typ' IEnumerable 'implementiert, was eine andere Sache ist und eine andere Lösung benötigt (wie durch die verschiedenen angenommenen Antworten bewiesen) – Jcl

Antwort

22

Die folgende Zeile

return (type is IEnumerable); 

ist "wenn eine Instanz von Type, type ist IEnumerable", das nicht der Fall, die eindeutig zu fragen.

Sie tun möchten, ist:

return typeof(IEnumerable).IsAssignableFrom(type); 
+0

@Octopoid eine Zeichenkette implementiert 'IEnumerable ', also ist es zutreffend, denn das ist, was Sie für – Jcl

+0

@Octopoid fragen Das ist das korrekte Verhalten. 'string' ist ein' IEnumerable ', was ein' IEnumerable' ist. –

+0

Ja, 'string' qualifiziert sich, aber in diesem Fall muss ich es wirklich ausschließen - es ist wahrscheinlich eher eine Frage der Methodenbenennung in diesem Stadium.Ich denke, ich lasse das so, wie es ist, und füge ein weiteres hinzu, das zuerst die Zeichenfolgen zuerst eintippt. – Octopoid

2

Neben Type.IsAssignableFrom(Type), können Sie auch Type.GetInterfaces() verwenden können:

public static void ImplementsInterface(this Type type, Type interface) 
{ 
    bool implemented = type.GetInterfaces().Contains(interface); 
    return implemented; 
} 

auf diese Weise, wenn Sie mehrere Schnittstellen überprüfen wollte ImplementsInterface leicht ändern könnte um mehrere Schnittstellen zu nehmen.

Verwandte Themen