kann nicht Typ ‚string‘ konvertiert ‚int?‘ über eine Referenz Umwandlung, Boxen-Konvertierung, Konvertierung unboxing, Umhüllen Wandlungs- bzw. null Typkonvertierung

StackOverflow https://stackoverflow.com/questions/887943

  •  23-08-2019
  •  | 
  •  

Frage

C # akzeptiert folgende Möglichkeiten:

object o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

Aber nicht

String o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

Ich frage mich nur über das Verhalten des Stichwort as in C #.

Das gleiche wie in Java würde dies fehlschlagen:

Object test1 = "hello";
Integer test2 = (Integer) test1;
String test3 = "hello";
Integer test4 = (Integer) test3; //compilation error
War es hilfreich?

Lösung

Der Compiler weiß, dass ein String nie ein int? sein kann, so sagt es Ihnen. Das bedeutet nicht, dass int? nicht sinnvoll ist. Ihr versucht Anwendungsfall ist weit von der normalen. Der normale ist „I eine ganze Zahl und die Möglichkeit darstellen wollen, dass der Wert fehlt / unbekannt“. Dafür arbeitet int? sehr gut.

Warum würden Sie erwartet Ihr Original-Code zu arbeiten? Warum wäre es hilfreich sein?

Beachten Sie, dass können Verwendung as mit Nullable-Typen, für Unboxing:

object o = "hello";
int? i = o as int?;

if (i == null)
{
    // o was not a boxed int
}
else
{
    // Can use i.Value to recover the original boxed value
}

EDIT: Nachdem Ihr Kommentar gesehen, nicht wahr as verwenden, um die Dinge zu analysieren. Sie wollen wahrscheinlich verwenden int.TryParse :

string text = "123":
int value;
if (int.TryParse(text, out value))
{
    Console.WriteLine("Parsed successfully: {0}", value);
}
else
{
    Console.WriteLine("Unable to parse text as an integer");
}

Wenn Sie sicher sind, dass die Zeichenfolge gemeint ist, eine ganze Zahl zu sein (dh es ist ein Fehler anders), dann können Sie nur ein href verwenden <= "http://msdn.microsoft.com/en-us/library/system .int32.parse.aspx“rel = "noreferrer"> int.Parse :

int value = int.Parse(text);

Das wird eine Ausnahme ausgelöst, wenn die Analyse nicht.

Beachten Sie auch, dass diese beiden Methoden können Sie ein Format-Provider (in der Regel eine Kultur info) spezifizieren, die Sie Zahlen ausdrücken können, wie in diesem Format ausgedrückt werden (z Tausendertrennzeichen).

EDIT: In Antwort auf Ihre neue Frage, der Compiler dies verhindert, weil es eine Reihe kennt, kann nicht möglicherweise ein boxed int sein - die Umwandlung wird nie gelingen. Wenn es weiß nur, dass der ursprüngliche Wert ist ein Objekt, es Macht erfolgreich zu sein.

Zum Beispiel: Angenommen, sagte ich zu ihr: „Hier ist eine Form: ist es ein Quadrat“ Das ist eine vernünftige Frage. Es ist vernünftig, es zu fragen. Sie nicht, ohne auf die Form kann sagen,

Wenn aber, sagte ich: „Hier ist ein Dreieck: ist es ein Quadrat“ Dann würde man vernünftigerweise berechtigt, in meinem Gesicht zu lachen, als ein Dreieck nicht möglicherweise ein Quadrat sein kann -. Die Frage nicht sinnvoll

Andere Tipps

int? bedeutet einen NULL festlegbaren Integer-Typen, und kein int, das jede andere Art von Variable enthalten könnte.

Wenn Sie einen Variablentyp mögen, die einen int oder eine Zeichenfolge enthalten könnten, würde Sie ein Objekt verwenden müssen, oder einen String nehme ich an, und dann ein Leben mit Typ-Casting gefüllt leben. Ich weiß nicht, warum Sie das tun wollen, though.

int? können Sie einen beliebigen ganzzahligen Wert oder einen Nullwert speichern. Welche ist nützlich, wenn die Antwort auf die Frage sagen: „Wie viele Aufträge diese Person gesetzt hat“ ist legitim „Ich weiß nicht“ anstelle einer Anzahl von Aufträgen, oder Null, das wäre: „Ich weiß für eine Tatsache, diese Person hat nie plaziert ein Auftrag“.

Ich möchte einige weitere Informationen hinzuzufügen.

Ein anderer Fall ist, warum die Besetzung ungültig ist und der Compiler einen Fehler auf Kompilation wirft, ist, dass System.String markiert ist als versiegelt . So weiß der Compiler, von dem Typ System.String inherites und auf welche Arten Sie die Zeichenfolge werfen können mit dem wie -Operator.

Durch das Schlüsselwort versiegelt , der Compiler weiß auch, dass Sie nicht erben von System.String Funktionen hinzuzufügen oder einige zusätzliche Schnittstellen implementieren .

Der folgende Code ist ein Beispiel und die Compiler die folgenden Fehler auf Kompilation

werfen
  

Kann nicht konvertieren Typ ‚SealedClass‘ zu   ‚ICastToInterface‘ über eine Referenz   Umwandlung, Boxen Umwandlung,   Unboxing Konvertierung, Wrapping   Konvertierung oder null Typumwandlung

public class UnsealedClass {
  // some code
}

public sealed class SealedClass {
  // some code
}

public interface ICastToInterface {
  // some code
}

public class Test {

  public Test() {
    UnsealedClass unsealedClass = new UnsealedClass();

    SealedClass sealedClass = new SealedClass();

    ICastToInterface unsealedCast = unsealedClass as ICastToInterface;  // This works fine

    ICastToInterface sealedCast = sealedClass as ICastToInterface; // This won´t compile, cause SealedClass is sealed
  }
}

Sie können jedoch den Wert von null überprüfen und setzen Sie ihn auf Null.

int? blah;
if (blah == null)
{}

int? ist ein nullable integer, es hat nichts mit Gießen und das als Schlüsselwort zu tun hat. „String“ ist ein String-Typ-Objekt, das nicht umwandelbar in ein int (NULL festlegbaren oder nicht-nullable).

Die als Schlüsselwort ist praktisch die gleiche wie Guss Klammern außer es verwendet, wird eine Fehlermeldung nicht zurück, es wird das Objekt auf null gesetzt:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

Das erste Beispiel funktioniert als das Objekt o zugewiesen ist ein int.

Nun betrachten:

string i = "MyString";

object o = MyString;

 int j = (int)o //unboxing raises exception

 int j = o as int; //raises compilation Error as int is not nullable
 int? j = o as int?; /// o == null

Ich hoffe, dass das hilft, den Unterschied zwischen den beiden Begriffen zu erklären.

Richard

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