Betrachten Sie den folgenden Code:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
Was ist der Unterschied zwischen den drei Arten von Casting (okay, das dritte ist kein Casting, aber Sie haben die Absicht). Welches sollte bevorzugt werden?
string s = Convert.ToString(o)
; 5.string s = $"{o}"
(oder gleichwertig dasstring.Format
Formular für frühere C #)Antworten:
Wirft InvalidCastException , wenn
o
nicht einstring
. Andernfalls Abtretungsempfängero
zus
, auch wenno
istnull
.Weist
null
zu,s
wenno
nicht einstring
oder wenno
istnull
. Aus diesem Grund können Sie es nicht mit Werttypen verwenden (der Operator könntenull
in diesem Fall niemals zurückkehren ). Andernfalls ordneto
ans
.Verursacht eine Nullreferenceexception , wenn
o
istnull
. Weisto.ToString()
zus
, was auch immer zurückgegeben wird , unabhängig davon, um welchen Typ es sicho
handelt.Verwenden Sie 1 für die meisten Conversions - es ist einfach und unkompliziert. Ich benutze fast nie 2, da ich normalerweise eine Ausnahme erwarte, wenn etwas nicht der richtige Typ ist. Ich habe nur einen Bedarf für diese Funktion vom Typ return-null mit schlecht gestalteten Bibliotheken gesehen, die Fehlercodes verwenden (z. B. return null = error, anstatt Ausnahmen zu verwenden).
3 ist keine Besetzung und nur ein Methodenaufruf. Verwenden Sie diese Option, wenn Sie die Zeichenfolgendarstellung eines Nicht-Zeichenfolgenobjekts benötigen.
quelle
string s = (string)o;
Verwenden Sie, wenn etwas definitiv das andere sein sollte.string s = o as string;
Verwenden Sie, wenn etwas sein könnte die andere Sache.string s = o.ToString();
Verwenden Sie diese Option, wenn Sie sich nicht darum kümmern, was es ist, sondern nur die verfügbare Zeichenfolgendarstellung verwenden möchten.quelle
Es hängt wirklich davon ab, ob Sie wissen, ob
o
es sich um eine Zeichenfolge handelt und was Sie damit machen möchten. Wenn Ihr Kommentar bedeutet, dass es sicho
wirklich wirklich um eine Zeichenfolge handelt, würde ich die gerade(string)o
Besetzung bevorzugen - es ist unwahrscheinlich, dass sie fehlschlägt.Der größte Vorteil der Verwendung der geraden Besetzung besteht darin, dass Sie bei einem Fehlschlag eine InvalidCastException erhalten , die Ihnen ziemlich genau sagt, was schief gelaufen ist.
as
Wenn der Operatoro
keine Zeichenfolge ist,s
wird er auf gesetzt.null
Dies ist praktisch, wenn Sie sich nicht sicher sind und testen möchtens
:Wenn Sie diesen Test jedoch nicht durchführen, werden Sie ihn
s
später verwenden und eine NullReferenceException auslösen . Diese sind in der Regel häufiger und viel schwerer zu finden, wenn sie in freier Wildbahn auftreten, da fast jede Zeile eine Variable dereferenziert und möglicherweise eine wirft. Wenn Sie dagegen versuchen, in einen Werttyp (ein Grundelement oder Strukturen wie DateTime ) umzuwandeln , müssen Sie die gerade Umwandlung verwenden - dasas
funktioniert nicht.Im speziellen Fall der Konvertierung in eine Zeichenfolge hat jedes Objekt eine
ToString
, sodass Ihre dritte Methode möglicherweise in Ordnung ist, wenn sieo
nicht null ist und Sie der Meinung sind, dass dieToString
Methode möglicherweise das tut, was Sie wollen.quelle
as
mit nullbaren Werttypen verwenden. IEo as DateTime
wird nicht funktionieren, abero as DateTime?
wird ...if (s is string)
stattdessen verwenden?is
Ing sowieso wieder besetzen, also hast du das Ist und dann eine harte Besetzung. Aus irgendeinem Grundas
fühlte sich der und null Check für mich besser an.Wenn Sie bereits wissen, in welchen Typ es umgewandelt werden kann, verwenden Sie eine Besetzung im C-Stil:
Beachten Sie, dass Sie nur mit einer Besetzung im C-Stil expliziten Typzwang ausführen können.
Wenn Sie nicht wissen, ob es sich um den gewünschten Typ handelt, und ihn gegebenenfalls verwenden, verwenden Sie ihn als Schlüsselwort:
Beachten Sie, dass as keine Typkonvertierungsoperatoren aufruft. Es ist nur dann nicht null, wenn das Objekt nicht null und nativ vom angegebenen Typ ist.
Verwenden Sie ToString (), um eine für Menschen lesbare Zeichenfolgendarstellung eines Objekts zu erhalten, auch wenn es nicht in eine Zeichenfolge umgewandelt werden kann.
quelle
Das Schlüsselwort as ist in asp.net gut, wenn Sie die FindControl-Methode verwenden.
Dies bedeutet, dass Sie die typisierte Variable bearbeiten können, anstatt sie dann
object
wie bei einer direkten Umwandlung umwandeln zu müssen:Es ist keine große Sache, aber es spart Codezeilen und Variablenzuweisungen und ist besser lesbar
quelle
'as' basiert auf 'is', einem Schlüsselwort, das zur Laufzeit prüft, ob das Objekt polimorphisch kompatibel ist (im Grunde genommen, wenn eine Umwandlung vorgenommen werden kann) und bei fehlgeschlagener Prüfung null zurückgibt.
Diese beiden sind gleichwertig:
Verwenden von 'as':
Verwenden von 'ist':
Im Gegenteil, der Cast im C-Stil wird auch zur Laufzeit erstellt, löst jedoch eine Ausnahme aus, wenn der Cast nicht erstellt werden kann.
Nur um eine wichtige Tatsache hinzuzufügen:
Das Schlüsselwort 'as' funktioniert nur mit Referenztypen. Du kannst nicht tun:
In diesen Fällen müssen Sie Casting verwenden.
quelle
2 ist nützlich zum Gießen auf einen abgeleiteten Typ.
Angenommen, a ist ein Tier:
erhält eine gefüttert mit einem Minimum von Abgüssen.
quelle
Laut Experimenten auf dieser Seite: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(Auf dieser Seite werden manchmal einige "illegale Verweis" -Fehler angezeigt. Aktualisieren Sie sie daher einfach, wenn dies der Fall ist.)
Die Schlussfolgerung ist, dass der "as" -Operator normalerweise schneller als ein Cast ist. Manchmal um ein Vielfaches schneller, manchmal nur knapp schneller.
Ich persönlich habe "as" auch besser lesbar.
Da es sowohl schneller als auch "sicherer" ist (keine Ausnahme auslöst) und möglicherweise einfacher zu lesen ist, empfehle ich, immer "als" zu verwenden.
quelle
"(string) o" führt zu einer InvalidCastException, da keine direkte Umwandlung erfolgt.
"o als Zeichenfolge" führt dazu, dass s eine Nullreferenz ist und keine Ausnahme ausgelöst wird.
"o.ToString ()" ist an sich keine Besetzung, sondern eine Methode, die von jedem Objekt und damit auf die eine oder andere Weise von jeder Klasse in .net implementiert wird, die mit der Instanz von "etwas" macht Die Klasse, für die es aufgerufen wird, gibt eine Zeichenfolge zurück.
Vergessen Sie nicht, dass es für die Konvertierung in Zeichenfolgen auch Convert.ToString (someType instanceOfThatType) gibt, bei dem someType zu einer Reihe von Typen gehört, im Wesentlichen zu den Framework-Basistypen.
quelle
Alle gegebenen Antworten sind gut, wenn ich etwas hinzufügen darf: Um die Methoden und Eigenschaften des Strings (z. B. ToLower) direkt zu verwenden, können Sie nicht schreiben:
du kannst nur schreiben:
aber du könntest stattdessen schreiben:
Die
as
Option ist besser lesbar (zumindest meiner Meinung nach).quelle
(o as string).ToLower()
anstelle der mehreren verwirrenden Klammern verwenden.Wird bevorzugt, da dadurch die Leistungseinbußen beim Doppelcasting vermieden werden.
quelle
Es scheint, dass die beiden konzeptionell unterschiedlich sind.
Direktes Casting
Typen müssen nicht eng miteinander verbunden sein. Es kommt in allen Arten von Geschmacksrichtungen.
Es fühlt sich an, als würde das Objekt in etwas anderes umgewandelt.
AS-Operator
Typen haben eine direkte Beziehung. Wie in:
Es fühlt sich so an, als würden Sie das Objekt anders behandeln.
Proben und IL
quelle
Ich möchte auf die folgenden Besonderheiten des as- Betreibers aufmerksam machen:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
quelle
Wenn ich versuche, die Zeichenfolgendarstellung von irgendetwas (von irgendeinem Typ) zu erhalten, das möglicherweise null sein könnte, bevorzuge ich die folgende Codezeile. Es ist kompakt, ruft ToString () auf und behandelt Nullen korrekt. Wenn o null ist, enthält s String.Empty.
quelle
Da es niemand erwähnt hat, ist das, was der Instanz von Java per Schlüsselwort am nächsten kommt, Folgendes:
quelle
Verwenden Sie Direct Cast,
string s = (string) o;
wenn im logischen Kontext Ihrer Appstring
der einzig gültige Typ ist. Mit diesem Ansatz erhaltenInvalidCastException
und implementieren Sie das Prinzip von Fail-Fast . Ihre Logik ist davor geschützt, den ungültigen Typ weiterzuleiten oder bei Verwendung die NullReferenceException zu erhaltenas
Operator verwendet wird.Wenn die Logik verschiedene Arten erwartet werfen
string s = o as string;
und überprüfen Sie es aufnull
oder Verwendungis
Betreiber.In C # 7.0 wurde eine neue coole Funktion veröffentlicht, um die Besetzung zu vereinfachen und zu überprüfen, ob ein Muster übereinstimmt :
quelle
Die folgenden zwei Formen der Typkonvertierung (Casting) werden in C # unterstützt:
|
(Lebenslauf
• Konvertieren Sie den statischen Typ von v in den angegebenen Ausdruck in c
• Nur möglich, wenn der dynamische Typ von v c oder ein Subtyp von c ist
• Wenn nicht, wird eine InvalidCastException ausgelöst
|
v als C.
• Nicht tödliche Variante von (c) v
• Konvertieren Sie daher den statischen Typ von v in den angegebenen Ausdruck in c
• Gibt null zurück, wenn der dynamische Typ von v nicht c oder ein Subtyp von c ist
quelle