Autor Beitrag
FinalFantasy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 127

Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
BeitragVerfasst: Mo 17.10.05 14:28 
Hi,

wieso kann man ein Object in dem nur ein Integerwert steht nicht nach Double casten?
ausblenden C#-Quelltext
1:
2:
object i = 13;
double k = (double) i;

führt zu einem StackOverflow...
ausblenden C#-Quelltext
1:
2:
object i = 13.0;
double k = (double) i;

funktioniert jedoch!!

Mit Convert.ToDouble(i) kann man es zwar trotzdem "umwandeln", aber wieso geht der cast nicht?

Moderiert von user profile iconTino: C#-Tags hinzugefügt.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 17.10.05 15:39 
Hallo!

Vorsicht, Mutmaßung!!

object i = 13; wird wohl einen Integer als Objekt erstellen und keinen Double. Die werden anders im Speicher abgelegt, sodass der Cast schief geht.
Wenn Du aber object i = 13.0; benutzt, wird auf Grund des Kommas ein Double erstellt.

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
FinalFantasy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 127

Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
BeitragVerfasst: Mo 17.10.05 15:43 
Ja, dadrauf bin ich auch schon gekommen, aber nachdem was du schreibst, dürfte folgendes auch nicht funktionieren:

ausblenden C#-Quelltext
1:
2:
int i = 13;
double d = (double) i;


Das funktioniert aber!!!

Moderiert von user profile iconKlabautermann: C#-Tags hinzugefügt.
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 416


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Mo 17.10.05 15:50 
user profile iconFinalFantasy hat folgendes geschrieben:
Ja, dadrauf bin ich auch schon gekommen, aber nachdem was du schreibst, dürfte folgendes auch nicht funktionieren:
ausblenden C#-Quelltext
1:
2:
int i = 13;
double d = (double) i;

Das funktioniert aber!!!

Muss auch, du machst einen expliziten cast, der zur compile zeit bekannt ist.
Deshalb können JIT oder Compiler den überladenen Operator für explizetes Casting Int32 -> Double verwenden.
Bei einem object -> double ist das schlecht möglich. Hier versucht die CLR direkt einen Double aus der Box zu holen.
_Normalerweise_ solltest du ein null bei einem fehlgeschlagenen direct cast bekommen.
Da value types nicht null sein dürfen, springt er dir mit Anlauf ins Gesicht. :P


Was mir an deinen Threads auffällt: Kennst du keine Debugger oder benutzt du sie einfach nicht?
DEr Debugger vom VS oder der der beim .Net SDK dabeiliegt[meta]GuiDebugger in der Doku suchen[/meta] hätten dir genau gesagt, was hier passiert. Vor allem hätten sie dir gesagt, dass object i = 13 einen Int32 enthält. ;)
FinalFantasy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 127

Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
BeitragVerfasst: Mo 17.10.05 16:24 
user profile iconRobert_G hat folgendes geschrieben:

Muss auch, du machst einen expliziten cast, der zur compile zeit bekannt ist.
Deshalb können JIT oder Compiler den überladenen Operator für explizetes Casting Int32 -> Double verwenden.
Bei einem object -> double ist das schlecht möglich. Hier versucht die CLR direkt einen Double aus der Box zu holen.
_Normalerweise_ solltest du ein null bei einem fehlgeschlagenen direct cast bekommen.
Da value types nicht null sein dürfen, springt er dir mit Anlauf ins Gesicht. :P


Was mir an deinen Threads auffällt: Kennst du keine Debugger oder benutzt du sie einfach nicht?
DEr Debugger vom VS oder der der beim .Net SDK dabeiliegt[meta]GuiDebugger in der Doku suchen[/meta] hätten dir genau gesagt, was hier passiert. Vor allem hätten sie dir gesagt, dass object i = 13 einen Int32 enthält. ;)


Hmm, ok, die Erklärung klingt einleuchtend.

Ja ich kenne Debugger und ich benutze sie auch, wie ich schon geschrieben habe, war mir eigentlich auch klar, dass in dem Object ein Integer steht und kein Double.Deswegen ja auch meine Frage, wieso man einen Int casten kann, aber kein Object in dem ja auch nichts anderes als ein Int steht.
Dass der JIT Compiler jedoch versucht einen Double zu lesen, wo aber ein Int steht und deshalb ja eigentlich gar keinen Cast macht, zeigt mir leider kein Debugger.
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 416


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Mo 17.10.05 17:35 
user profile iconFinalFantasy hat folgendes geschrieben:
Dass der JIT Compiler jedoch versucht einen Double zu lesen, wo aber ein Int steht und deshalb ja eigentlich gar keinen Cast macht, zeigt mir leider kein Debugger.


Der Grund warum es knallt steht eigentlich schon oben. Für andere Leser nochmal im Klartext:

Ein "hard cast" [meta](Type)variable -> (Button)someControl; (IList)someCollection[/meta] versucht eine Umwandlung, ist keine Umwandlung möglich[meta]kein Operator für explizite/implizite Umwandlung vorhanden[/meta] -> wird null ausgespuckt.
Ein value type kann nicht null sein -> *kabumm*
Aber "safe cast" [meta]variable as Type -> someControl as Button; someCollection as IList;...[/meta] ist nicht auf value types anwendbar...

Deshalb hast du nur wenige Möglichkeiten:

ausblenden C#-Quelltext
1:
object d = 1.1;					


ausblenden C#-Quelltext
1:
2:
3:
// safe cast -> kabumm, wenn IConvertible nicht implementiert wird
IConvertible convertible = d as IConvertible;
double myDouble = convertible.ToDouble(NumberFormatInfo.CurrentInfo);


ausblenden C#-Quelltext
1:
double myDouble = Convert.ToDouble(d);					


ausblenden C#-Quelltext
1:
double MyDouble = Convert.ChangeType(d, typeof(double));					


Die performanteste und einfachste Lösung wäre es, den Wert nie in eine Box (Object) zu stecken. ;)
Generics sind genau dafür da (und natürlich um Schreibkram einzusparen).
Oder einfach so selten wie möglich einzelne value types umherschubsen. Kannst du mehrere zu einer Klasse bündeln hast du alle Vorteile von reference types[meta]und Ordnung[/meta].
Wobei value types wiederum durch den JIT besser optimiert werden können... :autsch: