Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Warum können objects mit einem Werttypen, nicht in einen anderen Werttypen gecastet werden?
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

Warum können objects mit einem Werttypen, nicht in einen anderen Werttypen gecastet werden?

beantworten | zitieren | melden

Servus,

ich hab eine Verständnis frage:

Ursprünglich wollte ich folgendes machen:


List<uint> l1 = new List<uint> { 1, 2, 3 };
var l2 = l1.Cast<int>().ToList();

Das wirft
Fehler
System.InvalidCastException: "Unable to cast object of type 'System.UInt32' to type 'System.Int32'."

Nun ja, das lässt sich ja einfach mit


var l2 = l1.Select(i => (int)i).ToList();
ersetzen, kein Problem.

Aber irgenwie hat mir das keine Ruhe gelassen, IEnumerable<T> Cast<T> ist folgendermaßen implementiert:


public static IEnumerable<T> Cast<T>(this IEnumerable source)
{
    foreach (object o in source)
        yield return (T)o;
}
Das Problem ist, dass der Wert in ein object gesteckt wird, dieser Code wirft die gleiche Exception:


uint i = 42;
object o = i;
int j = (int)o;
Erst dachte ich, Werttypen können nicht aus einem object zurück gecastet werden, aber folgerndes funktioniert:


int i = 42;
object o = i;
int j = (int)o;
Warum können objects, mit einem Werttypen, nicht in einen anderen Werttypen gecastet werden? Vor allem da ja in der Exception die korrekten Typen genannt werden, also warum kann er den Cast nicht ausführen?

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5991
Herkunft: Leipzig

beantworten | zitieren | melden

Ganz allgemein: [FAQ] Casten aber richtig: () / is / as
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16204

beantworten | zitieren | melden

Bei der "Umwandlung" von uint auf int handelt es sich im Endeffekt nicht um ein Cast sondern um ein Reassigment.
Hier brauchst Du die Convert.To-Methoden.
Zitat
Das Problem ist, dass der Wert in ein object gesteckt wird, dieser Code wirft die gleiche Exception:

Die Exception selbst kommt im Prinzip vom Unboxing:
Deine Quelle ist uint; aber das Unboxing erfolgt auf int - daher knallts.

Bezogen auf Dein Beispiel bräuchtest Du einen zusätzlichen Cast; dann klappts.
=> uint -> object -> uint -> int

uint i = 42;
object o = i;
int j = (int)(uint)o;

Aber => uint -> object -> int knallt.
Dass der "Cast" von unit auf int funktioniert liegt am expliziten Operator.

 public static implicit operator int(uint value) => Convert.ToInt32(value);

Dein Szenario deckt aber so Cast<T> nicht ab.
Cast ist eigentlich dafür da, dass Du zB. eine Collection eines Interfaces hast, das dann wiederum verschiedene Instanzen von Implementierungen hast, und dann durch das Cast die Implementierungen raus ziehen kannst.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 966

beantworten | zitieren | melden

Die Signatur sollte aber explicit sein, schließlich willst du ja ausdrücken dass nicht jedes uint in ein int umgewandelt werden kann und der Programmierer casten soll.
private Nachricht | Beiträge des Benutzers
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

beantworten | zitieren | melden

@MrSparkle:
Ich weiß, es mir nur klar zu machen um was es mir geht.

@Abt:
Super danke, an das Unboxing hab ich nicht gedacht.

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers