| 

.NET C# Java Javascript Exception

8
Hallo zusammnen,

ich habe gerade ein interessantes Problem gefunden, welches ich nicht erklären kann. Vielleicht könnt ihr mir ja helfen.

Ich habe folgenden Code:

private static void Main(string[] args)
{
var x = GetValue<int>(42);

var y = GetValue<long>(42);
}



private static T GetValue<T>(object obj)
{
if (obj == null || obj == DBNull.Value)
{
return default(T);
}

return (T)obj;
}


Wenn ich ein Int zurückhaben will, dann funktioniert es ohne Probleme, beim Rückgabewert long bekomme ich aber eine InvalidCastOperation an der Stelle return (T)obj.

Die Nachricht der Exception lautet: "Die angegebene Umwandlung ist ungültig.".

Kann mir jeman erklären, warum die Umwandlung ungültig sein soll ??

Zur Info.
Verwende Visual Studio 2010, .NET 4, Win7Pro 64 SP1
News:
19.11.2012
multi1209 848 1 8
+1 schöne frage, schönes thema... hat mich auch erst gewundert, aber wenn mans noch nich kennt ;) und so hab auch ich wieder was gelernt :D
Karill Endusa 19.11.2012
3 Antworten
2
Um die Exception abzustellen kannst du auch folgendes verwenden:
private static T GetValue<T>(object obj)
{
if (obj == null || obj == DBNull.Value)
{
return default(T);
}
return (T)Convert.ChangeType(obj, typeof(T));
}

Allerdings weiß ich nicht, wie performant ChangeType ist. Müsstest du dir dann mal näher anschauen.
19.11.2012
LunaticShade 507 4
Das ist genau was ich gesucht habe!
multi1209 20.11.2012
3
Folgender Eintrag in Eric Lippert's Blog geht auf das Thema sehr gut ein: http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx

In Short:
Das Problem hängt damit zusammen, was mit einer Umwandlung eines Wertes eines bestimmten Types nach Object passiert... Boxing!
Wie Eric Lippert schon so schön ganz am Anfang schreibt:
Because a boxed T can only be unboxed to T.

Würdest du demnach deiner GetValue auch ein long übergeben, müsste es gehen...
var y = GetValue<long>((long)42);
getestet und funktioniert...

Andererseits, wie auch im oben erwähnten Blog zu lesen:
Int nach Int unboxen und anschließend casten sollte ebenso gehen...

Abschließend:
Da du anscheinend auf diesem Weg an Daten aus einer Datenquelle kommen willst, sollte das kein Problem darstellen. Das Object, welches du ausließt, sollte in diesem Fall ein boxed long sein und es sollte zu keiner InvalidCastException kommen...

so far
Karill Endusa
19.11.2012
Karill Endusa 1,5k 1 9
Ja die Erklärung ist auch einleuchtend, wenn man genauer darüber anchdenkt. Man würde ja auch nicht versuchen zunächst ein komplexes Objekt zu "boxen" und dan beim unboxing ein Cast auf int machen. Bei int und long war das nur nicht auf den ersten Blick zu sichtbar, da ein cast con int zu long ja normalerweise kein Problem ist.
multi1209 20.11.2012
wollte auch nie sagen, dass es "offensichtlich" ist... wie bereits in meinem Kommentar zu deiner Frage geschrieben, war auch mir das neu :)
Hatte mich vorher noch nie mit Un/Boxing genauer beschäftigt, aber im Endeffekt leuchet es ein...
Karill Endusa 20.11.2012
1
Hallo,

da ein Unboxen zu einem unterschiedlichen Typ nicht möglich ist. Der Typ ist hier int und beim Unbox kann daraus kein long werden.

Wenn du explizit long übergibts, also 42L, so gehts.

mfG Gü
19.11.2012
gfoidl 9,4k 3 5

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH