Frage

Mögliches Duplikat:
Casting vs. Verwendung des Schlüsselworts „as“ in der CLR

Was ist eigentlich der Unterschied zwischen diesen beiden Besetzungen?

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

Normalerweise sollten beide explizite Umwandlungen in den angegebenen Typ sein?

War es hilfreich?

Lösung

Ersteres löst eine Ausnahme aus, wenn der Quelltyp nicht in den Zieltyp umgewandelt werden kann.Letzteres führt dazu, dass sc2 eine Nullreferenz ist, aber keine Ausnahme.

[Bearbeiten]

Meine ursprüngliche Antwort ist sicherlich der deutlichste Unterschied, aber als Eric Lippert weist darauf hin, es ist nicht das einzige.Weitere Unterschiede sind:

  • Sie können den Operator „as“ nicht für die Umwandlung in einen Typ verwenden, der „null“ nicht als Wert akzeptiert
  • Sie können „as“ nicht verwenden Konvertieren Dinge wie Zahlen in eine andere Darstellung (z. B. float in int).

Und schließlich die Verwendung von „as“ vs.Als Cast-Operator sagen Sie auch: „Ich bin mir nicht sicher, ob das gelingen wird.“

Andere Tipps

Beachten Sie außerdem, dass Sie das Schlüsselwort as nur mit einem Referenztyp oder einem Nullable-Typ verwenden können

dh:

double d = 5.34;
int i = d as int;

wird nicht kompiliert

double d = 5.34;
int i = (int)d;

wird kompilieren.

Die Typumwandlung mit „as“ ist natürlich viel schneller, wenn die Umwandlung fehlschlägt, da dadurch die Kosten für das Auslösen einer Ausnahme vermieden werden.

Aber schneller geht es nicht, wenn die Besetzung gelingt.Die Grafik unter http://www.codeproject.com/KB/cs/csharpcasts.aspx ist irreführend, weil es nicht erklärt, was es misst.

Das Endergebnis ist:

  • Wenn Sie davon ausgehen, dass die Besetzung erfolgreich ist (d. h.ein Misserfolg wäre die Ausnahme), verwenden Sie einen Gipsverband.

  • Wenn Sie nicht wissen, ob es erfolgreich sein wird, verwenden Sie den Operator „as“ und testen Sie das Ergebnis auf Null.

Ein Unterschied zwischen den beiden Ansätzen besteht darin, dass das erste ((SomeClass)obj) a verursachen kann Typkonverter heißen.

Hier ist eine gute Möglichkeit, sich an den Prozess zu erinnern, dem jeder von ihnen folgt und den ich verwende, wenn ich versuche zu entscheiden, welcher für meine Situation besser ist.

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

und das nächste sollte leicht zu erraten sein, was es tut

DateTime i = value as DateTime;

Im ersten Fall wird eine Ausnahme ausgelöst, wenn der Wert nicht umgewandelt werden kann. Im zweiten Fall, wenn der Wert nicht umgewandelt werden kann, wird i auf null gesetzt.

Im ersten Fall wird also ein harter Stopp durchgeführt, wenn die Umwandlung fehlschlägt, im zweiten Fall wird ein weicher Stopp durchgeführt, und es kann später zu einer NullReferenceException kommen.

Also Der „as“-Operator „hilft“ Ihnen, Ihr Problem viel tiefer zu vergraben Denn wenn eine inkompatible Instanz bereitgestellt wird, gibt sie Null zurück. Möglicherweise übergeben Sie diese an eine Methode, die sie an eine andere weitergibt usw., und schließlich erhalten Sie eine NullReferenceException, die das Debuggen erschwert.

Missbrauche es nicht.Der Direct-Cast-Operator ist in 99 % der Fälle besser.

Zur Erweiterung Kommentar von Rytmis, Sie können das nicht verwenden als Schlüsselwort für Strukturen (Werttypen), da sie keinen Nullwert haben.

Dies gilt alles für Referenztypen, Werttypen können das nicht verwenden as Schlüsselwort, da sie nicht null sein dürfen.

//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;


//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;

Die Cast-Syntax ist schneller, aber nur bei Erfolg ist es viel langsamer, dass sie fehlschlägt.

Die beste Vorgehensweise ist die Verwendung as Wenn Sie den Typ nicht kennen:

//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;

//use as to find the right type
if( ( sc = someObject as SomeClass ) != null ) 
{
    //do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null ) 
{
    //do something with soc
}

Allerdings, wenn Sie sich dessen absolut sicher sind someObject ist ein Beispiel für SomeClass dann verwende cast.

In .Net 2 oder höher bedeuten Generika, dass Sie sehr selten eine untypisierte Instanz einer Referenzklasse benötigen, sodass letztere seltener verwendet wird.

Die Umwandlung in Klammern löst eine Ausnahme aus, wenn der Umwandlungsversuch fehlschlägt.Die „as“-Umwandlung gibt null zurück, wenn der Umwandlungsversuch fehlschlägt.

Sie werden verschiedene Ausnahmen auslösen.
() :NullReferenceException
als :InvalidCastException
Was beim Debuggen hilfreich sein könnte.

Das Schlüsselwort „as“ versucht, das Objekt umzuwandeln. Wenn die Umwandlung fehlschlägt, wird null stillschweigend zurückgegeben.Der ()-Umwandlungsoperator löst sofort eine Ausnahme aus, wenn die Umwandlung fehlschlägt.

„Verwenden Sie das C#-Schlüsselwort „as“ nur dann, wenn Sie erwarten, dass die Umwandlung in einem nicht außergewöhnlichen Fall fehlschlägt.Wenn Sie davon ausgehen, dass eine Umwandlung erfolgreich ist, und nicht darauf vorbereitet sind, ein Objekt zu erhalten, das fehlschlagen würde, sollten Sie den Umwandlungsoperator () verwenden, damit eine geeignete und hilfreiche Ausnahme ausgelöst wird.

Für Codebeispiele und eine weitere Erklärung: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

Es ist wie der Unterschied zwischen Parse und TryParse.Sie verwenden TryParse, wenn Sie damit rechnen, dass es fehlschlägt, aber wenn Sie sicher sind, dass es nicht fehlschlägt, verwenden Sie Parse.

Für diejenigen unter Ihnen mit VB.NET-Erfahrung: (Typ) ist dasselbe wie DirectCast und „als Typ“ ist dasselbe wie TryCast.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top