Frage an clr, c#, casting, .net-4.0 – C # -Umwandlung in einen nullfähigen Typ?

28

Darüber hinaus der regelmäßige langweilige Unterschied zwischenCast undAs

wenn ichkennt DasApfel ist einObst also kann ich benutzen(Fruit)apple - und es löst eine Ausnahme aus, wenn es nicht istas value kann mit null verglichen werden, um zu sehen, ob dies erfolgreich war. [Ausnahme wird nicht ausgelöst ...]

Allerdings habe ich @ EricLippert gelesenArtikel dazu und es gab ein schönes Beispiel über Nullable Value Types:

<code>short? s = (short?)123;
int? i = s as int?;
</code>

dieseGewohnheit kompilieren...

Typ 'short?' Kann nicht konvertiert werden zu 'int?' über eine Referenzkonvertierung, Boxing-Konvertierung, Unboxing-Konvertierung, Wrapping-Konvertierung oder Null-Typ-Konvertierung

Fein.

also warum das:

<code>    short? s = (short?)123;
    int? i = (int?)s;
</code>

Tut Kompilieren? (Gegen ALLE Erwartungen ! ichKENNT Dass ist nichtint? - und es sollte knallen, aber es ist nicht ...)

Die Cast-Überprüfung hier sollte viel tödlicher sein als das vorherige Beispiel (das Bang ging).

Es tut mir leid, nach diesem viel diskutierten Thema zu fragen.

Danke im Voraus.

Und noch etwas -int? i2 = (object)s as int?; - kehrt tatsächlich zurücknull NSGaga
@ RoyiNamir Versuchen Sie zu kompilierenint i = 123 as int; und der Fehler lautet "Der as-Operator muss mit einem Referenztyp verwendet werden ('int' ist ein Werttyp)".int i = (int)123; auf der anderen Seite wird perfekt kompiliert. Mr Lister
@Yahia aber sind wir uns einig, dass kurz NICHT INT ist? Royi Namir
Sie haben genau das beschrieben, was Eric Lippert schrieb - die Besetzung würde kompilieren, während dieas Operator wird nicht für Fälle in Bezug auf nullbare Typen. Yahia

Deine Antwort

4   die antwort
0

Ich denke, es liegt anas Fehler erhalten Sie eine "gültige"null Ergebnis, sofalsch positiv. Im zweiten Fall ist die Umwandlung zulässig, da sie im Falle eines Fehlers eine Ausnahme auslöst.

0

Der Grund ist das int? ist nur eine Abkürzung fürSystem.Nullable<int> (System.Nullable<T> ist der Typ). Der Kurztyp definiert jedoch eine explizite Umwandlung in ein intSystem.Nullable<T> hat keine solche explizite Umwandlung, da T ein beliebiger anderer Werttyp sein kann.

4

Das Beispiel:

<code>int? i = (int?)s;
</code>

Tut Compiler, weil eine Besetzung bedeutet, dass Sie dem Compiler mitteilen, dass Sie etwas wissen, worauf er nicht schließen kann, das heißt, dasss kann zu einem konvertiert werdenint?.

Sie erhalten die Ausnahme nur zur Laufzeit, wenn die Umwandlung nicht erfolgreich ist.

@ RoyiNamir - Sorry, hätte das nur für den Fall hinzufügen sollen, dass die Besetzung nicht funktioniert. Oded
Es gibt keine Ausnahme zur Laufzeit ..... Royi Namir
25

In Ihrem ersten Beispiel ist dasas Der Operator versucht, das Objekt zu verwendens als einint?. Schon seitint? ist nirgends in der Vererbungskette vonshort?schlägt dieser Vorgang fehl.

In Ihrem zweiten Beispiel erstellen Sie tatsächlich ein neuesint? i mit dem Wert vonshort? s. Dies ist eine großzügigere Operation, da das Original nicht aufbewahrt werden musss Objekt auf der linken Seite.

Der wichtige Punkt hier ist dasas darf nichts tun, was die Identität Ihres Objekts nicht bewahrt. Eine explizite Besetzung kann.

Hier ist, was der C # -Standard darüber sagt, wie die(int?) Formular funktioniert:

6.1.4 Implizite nullwertfähige Konvertierungen

Vordefinierte implizite Konvertierungen, die für nicht nullfähige Werttypen ausgeführt werden, können auch für nullfähige Formen dieser Typen verwendet werden. Für jede der vordefinierten impliziten Identitäts- und numerischen Konvertierungen, die von einem nicht nullbaren Werttyp S in einen nicht nullbaren Werttyp T konvertieren, gibt es die folgenden impliziten nullbaren Konvertierungen:

· Eine implizite Konvertierung von S? nach T ?.

· Eine implizite Konvertierung von S nach T ?.

Die Auswertung einer impliziten nullwertfähigen Konvertierung auf Basis einer zugrunde liegenden Konvertierung von S in T erfolgt wie folgt:

· Wenn die Nullable-Konvertierung von S? zu T ?:

o Wenn der Quellwert null ist (die HasValue-Eigenschaft ist false), ist das Ergebnis der Nullwert vom Typ T ?.

o Andernfalls wird die Konvertierung als ein Auspacken von S? in S, gefolgt von der zugrunde liegenden Umwandlung von S in T, gefolgt von einem Umbruch (§4.1.10) von T in T ?.

· Wenn die nullfähige Konvertierung von S nach T erfolgt, wird die Konvertierung als die zugrunde liegende Konvertierung von S nach T ausgewertet, gefolgt von einem Umbruch von T nach T.

@ RoyiNamir, ich verstehe nicht wirklich. Eine Konvertierung existiert vonshort zuint (Dies gilt für C, Java und so ziemlich überall sonst.) In der C # -Spezifikation wird beschrieben, wie diese Konvertierung vorgenommen und für nullfähige Typen verwendet werden kann. (Ich habe den entsprechenden Auszug oben hinzugefügt.) sblom
@sblom Ich denke du solltestdouble-bold der obige Absatz sagtThe important point here is that as isn't allowed to do anything that doesn't preserve your object's identity. An explicit cast can. - Ich denke, das ist der Kern davon. Und was das Casting angeht, stimme ich zu, das ist mir klar (as war nicht wirklich), und wie Eric sagte, gibt es keine Arithmetik für short-s (das ist eigentlich egal, aber für mich ist die Konvertierung einfacher zu verstehen), sie konvertiert in int. NSGaga
Jenseits dieser Erklärung gibt es noch diese Zeile(int?)s welche DO im Zusammenhang mit Vererbung / Box-Ära ... aber es funktioniert und das ist die Sache, die ich nicht verstehe. Royi Namir

Verwandte Fragen