2009-07-15 11 views
25

Ein Kollege hat mir heute eine interessante Frage gestellt - ist das C# -Schlüsselwort/-Operator "wird" als Reflexion betrachtet?C# "ist" Operator - ist das Reflexion?

object tmp = "a string"; 
if(tmp is String) 
{ 
} 

Wie wird dieser Operator hinter den Kulissen implementiert? Braucht es Reflexion oder Introspektion? Oder ist der Typ des Objekts aufgrund der stark typisierten Sprache sofort als Attribut der obersten Ebene des Objekts im Speicher verfügbar?

MSDN heißt es:

Beachten Sie, dass der Betreiber der Ansicht ist nur als Referenz Conversions, Boxen Conversions und Unboxing-Konvertierungen. Andere Konvertierungen, z. B. benutzerdefinierte Konvertierungen, werden vom is-Operator nicht berücksichtigt.

Die Möglichkeit, Boxed und Unboxed Konvertierungen in Betracht zu ziehen, scheint mir eine Art Introspektion zu bedeuten.

+0

bezogen http://stackoverflow.com/questions/57701/what-are-the-performance-characteristi-s-of-is-reflection-in-c?lq=1 – nawfal

Antwort

31

Referencing ECMA-335 erzeugt der Bediener die isisinst Objektmodell IL Anweisung (Partition III §4.6), der Teil der Reflexions Bibliothek zu sein (Partition IV §5.5) im Gegensatz gesetzt Teil des Basis-Befehls ist.

Edit: Der Operator is ist sehr effizient im Vergleich zu der Reflexionsbibliothek. Sie könnten im Grunde den gleichen Test viel langsamer durch Reflexion durch:

typeof(T).IsAssignableFrom(obj.GetType()) 

Edit 2: Sie sind nicht korrekt über die Effizienz der castclass und isinst Anweisungen (die Sie nun aus dem Beitrag bearbeitet haben). Sie sind in jeder praktischen VM-Implementierung stark optimiert. Das einzige wirkliche Leistungsproblem ist das Potenzial für castclass, eine Ausnahme zu werfen, die Sie vermeiden, indem Sie den C# as-Operator und einen Test für null (für Referenztypen) oder den Operator is gefolgt von einem Cast (für Werttypen) verwenden.

+0

Ich habe nichts bearbeitet, aber vielleicht sollte ich klarstellen, was ich unter "teuer" verstehe. Ich weiß nicht viel über IL-Effizienz, aber FxCop hat eine Warnung, wenn Sie Code erstellen, der sowohl eine isinst- als auch eine casclass-Anweisung ausgibt, weil sie es als ineffizient oder "teuer" betrachten. –

+2

Wie ich in der zweiten Editierung erwähnt habe, sollten Sie 'As' gefolgt von einer' Null'-Prüfung für Referenztypen verwenden. Stattdessen hast du 'is' gefolgt von einem Cast benutzt, woraufhin FxCop dich alarmiert. –

+2

Für das, was es Wert ist, auf dem Compact Framework, IL, die RTTI (wie 'isinst' und' casclass') explizit überprüfen muss, ist so langsam wie Reflexion, während Callvirt hoch optimiert ist. Die Moral: Versuchen Sie, Typ-Case-Konstrukte zu vermeiden, bei denen virtuelle/abstrakte Methoden funktionieren können. –

5

Der Operator is legt im Wesentlichen fest, ob eine Umwandlung möglich ist. Statt jedoch eine Ausnahme auszulösen, wenn die Umwandlung unmöglich ist, wird false zurückgegeben. Wenn Sie über Reflexion nachdenken, dann ist dies auch eine Reflexion.

EDIT:

Nach einigen Recherchen habe ich entdeckt, dass eine Besetzung in IL på der castclass Anweisung ausgeführt wird, während die is Operator Karten auf den isinst Anweisung. FxCop hat eine rule, die Sie warnt, wenn Sie unnötige Umwandlungen durchführen, indem Sie zuerst die isinst und dann die castclass Anweisung verwenden. Obwohl die Vorgänge effizient sind, haben sie immer noch Leistungskosten.

+0

'ist' Operator gibt wahr/falsch und nicht zurück Null. – SolutionYogi

+1

Ich denke, Sie denken an den "as" -Operator – Matt

+0

Was Sie beschrieben haben, ist der "as" -Operator. Der 'ist' Operator ist im Wesentlichen die gleiche Operation, nur mit einem anderen Rückgabewert. – Charlie

1

Andere Sprachen haben Informationen zur Laufzeit, die ausreichen, um dynamisches Casting zu unterstützen, und nichts, was man als Reflexion bezeichnen könnte (C++ ist ein offensichtliches Beispiel).

Die Reflexion bezieht sich also auf zusätzliche Funktionen, die über die Erkennung eines Objekttyps hinausgehen. Das "Reflektieren" eines Objekts impliziert beispielsweise die Fähigkeit, seine Mitglieder zu gehen.

+0

Es wäre * korrekter zu sagen, dass Reflexion die Mitglieder einer Klasse analysiert als die eines Objekts, da Sie keine Instanz am Leben haben müssen. Außerdem ermöglicht Reflektion das "Entdecken" von Klassen, die Sie in einer Assembly haben, nicht nur von Mitgliedern und anderen Informationen einer Klasse. –

+0

@Danny Varod - Nicht alle Sprachen haben Klassen oder Assemblys. –

+0

C++ hat Klassen und Bibliotheken, Java hat Klassen und Pakete. Objektorientierte Programmierung definiert den Unterschied zwischen einem Objekt und einer Klasse. –