Frage

Ich habe eine IDataRecord reader, dass ich eine Dezimalzahl aus bin Abrufen wie folgt:

decimal d = (decimal)reader[0];

Aus irgendeinem Grund dies eine ungültige Cast Exception wirft sagen, dass die „angegebene Umwandlung ungültig ist.“

Wenn ich reader[0].GetType() es mir sagt, dass es ein Int32 ist. Soweit ich weiß, ist dies kein Problem ....

sein sollte

Ich habe das diesen Schnipsel erprobt, die ganz gut funktioniert.

int i = 3750;
decimal d = (decimal)i;

Das hat mich verlassen Kratzen meinem Kopf fragen, warum es versagt unbox die int im Leser als Dezimalzahl enthalten.

Weiß jemand, warum dies geschieht werden könnte? Gibt es etwas subtiler ich fehle?

War es hilfreich?

Lösung

Sie können nur einen Werttyp in seinen ursprünglichen Typ (und die Nullable-Version dieses Typs) unbox.

übrigens, dies gilt (nur eine Abkürzung für Ihre zwei Zeilenversion):

object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion

Aus dem Grund dahinter lesen Sie Eric Lippert Blogeintrag: Repräsentation und Identität

Ich persönlich kategorisieren Dinge durch Guss Syntax in vier verschiedene Arten von Operationen durchgeführt (sie alle unterschiedlich IL Anweisungen haben):

  1. Boxen (box IL-Anweisung) und Unboxing (unbox IL-Anweisung)
  2. die inhertiance Hierarchie durch Gießen (wie dynamic_cast<Type> in C ++, castclass IL-Befehl verwendet, um zu überprüfen)
  3. Casting zwischen primitiven Typen (wie static_cast<Type> in C ++, es gibt viele IL Anweisungen für die verschiedenen Arten von Abgüssen zwischen primitiven Typen)
  4. Benutzer aufrufen definiert Konvertierungsoperatoren (bei der IL-Ebene sind sie nur Methodenaufrufe an die entsprechende op_XXX Methode).

Andere Tipps

Es gibt kein Problem in Gießen einen int decimal, aber wenn Sie ein Objekt Unboxing Sie haben die genaue Art zu verwenden, die das Objekt enthält.

den int Wert in einen decimal Wert Um unbox, Sie es zuerst als int unbox, es dann auf Dezimal Stimmen:

decimal d = (decimal)(int)reader[0];

Die IDataRecord Schnittstelle hat auch Methoden für Unboxing den Wert:

decimal d = (decimal)reader.GetInt32(0);

Hier ist eine einfache Lösung. Es kümmert sich um Unboxing und dann in Dezimalzahlen Gießen. Funktionierte gut für mich.

decimal d = Convert.ToDecimal(reader[0]);  // reader[0] is int

Mehrdad Afshari sagte er:

  

Sie können nur unbox einen Werttyp in seinen ursprünglichen Typ (und die NULL-Werte zulassen   Version dieses Typs).

Das ist daran zu erkennen ist, dass gibt es einen Unterschied zwischen dem Gießen und Unboxing . jerryjvl hatte eine ausgezeichnete Bemerkung

  

In gewisser Weise ist es eine Schande, dass Unboxing und Casting syntaktisch aussehen   identisch, da sie sehr unterschiedliche Vorgänge.

Casting:

int i = 3750; // Declares a normal int
decimal d = (decimal)i; // Casts an int into a decimal > OK

Boxen / Unboxing:

object i = 3750; // Boxes an int ("3750" is similar to "(int)3750")
decimal d = (decimal)i; // Unboxes the boxed int into a decimal > KO, can only unbox it into a int or int?
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top