2009-11-02 8 views
6

Die üblichen und nicht so häufigen Verwendungsmuster für die C# -Schlüsselarbeit "ist". Ich habe es kürzlich verwendet, um die Anzahl der verwendeten Zellen in einem typisierten Array zu zählen (immer noch am unteren Rand mit xsd-generierten Klassen, da xsd2code eine Reihe von Problemen mit IETF-entworfenen Schemata hatte, also keine Generika).C# Nutzungsmuster für das Schlüsselwort "is"

Welche anderen gängigen und vor allem üblichen Nutzungsmuster werden angeboten.

+1

Ich denke, das gebräuchlichste Muster ist für das, was es tut ...(der Rest ist eher ungewöhnlich), wie in A ist B oder A implementiert B. –

Antwort

14

Das Schlüsselwort 'is' ist hilfreich, um zu bestimmen, ob ein Objekt über eine Referenz-, Boxing- oder Unboxing-Konvertierung in einen Typ konvertierbar ist (C# lang spec 7.9.10). Es ist ähnlich wie "as", außer dass es die Konvertierung nicht wirklich durchführt, sondern nur zurückkehrt, wenn es möglich ist.

Es ist nützlich in jedem Szenario, in dem zu wissen, ob ein Objekt in einen Typ konvertierbar ist, nützlich ist, aber das Objekt über eine Referenz auf diesen Typ ist nicht notwendig.

if (o is SomeType) { 
    TakeSomeAction(); 
} 

eine Referenz des angegebenen Typs auf den Wert Wenn mit nützlich ist, dann ist es effizienter, anstatt den ‚als‘ Operator zu verwenden.

// Wrong 
if (o is SomeType) { 
    SomeType st = (SomeType)o; 
    st.TakeSomeAction(); 
} 

// Right 
SomeType st = o as SomeType; 
if (st != null) { 
    st.TakeSomeAction(); 
} 
6

Eigentlich benutze ich es fast nie. Wenn ich es brauche, ist es normalerweise, weil ich den Wert sowieso auf den erforderlichen Typ umsetze, also verwende ich lieber als stattdessen.

Vergleich:

if (x is MyType) 
{ 
    MyType y = (MyType)x; 
    ... 
} 

Und:

MyType y = x as MyType; 
if (y != null) 
{ 
    ... 
} 

Im ersten Fall: 2 Operationen (1 Rückschlag + 1 cast)

Im zweiten Fall: 1-Betrieb (Typ check + cast in einem Schuss)

+0

Wenn mein Gedächtnis mir dient Nun, der emittierte Code ist im Grunde der gleiche –

+1

Ich habe gerade mit Reflector überprüft, es ist nicht ... Jedenfalls würde es nicht Sinnvoll, da diese beiden Ansätze semantisch verschieden sind (zum Beispiel kann 'as' nur mit Referenztypen verwendet werden) –

1

Ich kann mich nicht erinnern, jemals verwendet is. Wenn Sie wissen müssen, ob eine Instanz von einem bestimmten Typ ist, müssen Sie diese meistens verwenden.

Also bin ich es normalerweise direkt mit as oder explizite Casting, wenn ich sicher bin, dass es tatsächlich von der Art in Frage ist.

Ich versuche, Code zu schreiben, den es nicht benötigt, um Typinformation mehrmals zu werfen oder zu finden. Es ist also sicherlich nicht empfehlenswert is vor einem Cast eines Referenztyps zu schreiben.

+0

" is "vor einem Cast ist die einzige Möglichkeit," Objekte "sicher auf Werttypen zu" werfen "wie" will " in der Lage sein, eine Null zurückzugeben, die für Werttypen nicht unterstützt wird. –

+0

@Hans: ja du hast Recht, ich formuliere es um es für Referenztypen spezifisch zu machen. –

0

Mit dem kommenden v4 statt zu verwenden ist und da gibt es einen anderen möglichen Ansatz.

void somemethod(dynamic o) 
{ 
DoStuff(o); 
} 

DoStuff(neededType o){} 
DoStuff(object o){} 

, die jedoch einen performnce Hit macht haben könnte, aber für schöne Lesbarkeit

0

Es hängt davon ab, ob Sie einen Verweis auf die Art, wenn es is eine Art des angegebenen Typs benötigen. Wenn dies der Fall ist, sollten Sie `as keyworkd 'verwenden.

MyObject mo = obj as MyObject; 
if (mo == null) { 
    // do something. 
} else { 
    // do something else. 
} 

, die eine Referenz liefern würde, die Sie für null testen können. Andernfalls, mit dem as Optrator werden Sie am Ende sowieso aufgefordert, eine Besetzung durchzuführen.

Verwandte Themen