Casting-Null wird nicht kompiliert

8

versehentlich bei der Arbeit schrieb ich die folgende Codezeile:

%Vor%

Das hat mir einen Kompilierungsfehler ähnlich wie folgt gegeben: Can't cast source type object to target type string

Warum? Ist nicht null nur ein paar Nullen, die auf die Speicheradresse "Nirgendwo" zeigen, egal welcher Typ?

    
gdoron 25.01.2012, 18:43
quelle

7 Antworten

11

Die Frage hier ist im Grunde: "Warum berücksichtigt der Compiler nicht die Tatsache, dass er weiß, dass der zugewiesene Wert eine konstante Referenz ist, von der man weiß, dass sie null ist?"

Die Antwort lautet: Warum sollte es? Was ist der zwingende Vorteil, diese Informationen zu berücksichtigen? Sie haben absichtlich gesagt: "Ich möchte, dass dieser Ausdruck so behandelt wird, als ob er vom Typ Objekt wäre", und Sie können keinen Wert vom Typ Objekt einer Variablen vom Typ String zuweisen. Was ist der Vorteil, das in diesem Fall zuzulassen?

Der Code scheint mir sehr wahrscheinlich ein Bug zu sein; sicherlich sollte der Compiler davon erzählen, anstatt es zu erlauben.

    
Eric Lippert 25.01.2012, 18:56
quelle
23

Das Problem ist nicht die Umwandlung von null , sondern% object ist nicht string zuweisbar. Das funktioniert gut

%Vor%

Der Grund dafür, dass Sie den Cast ( string x = null ) entfernen, finden Sie in Abschnitt 2.4.4.6 der C # -Sprachspezifikation

  

Das Null-Literal kann implizit in einen Referenztyp oder Nullwerttyp

konvertiert werden

Sobald Sie einen Cast ( (object)null ) einführen, haben Sie kein Null-Literal mehr. Stattdessen haben Sie einen Wert vom Typ object . Es ist im Grunde nicht anders als

%Vor%     
JaredPar 25.01.2012 18:45
quelle
5
  

Ist nicht null nur eine Menge Nullen, die auf die Speicheradresse "nirgendwo" zeigen, egal um welchen Typ es sich handelt?

Das ist alles in einer schwach typisierten Sprache wie C oder C ++.

In C # ist der Typ einer Referenz ein wesentlicher Bestandteil ihrer Identität. (string)null ist nicht dasselbe wie (object)null , weil eins string und eins object ist.

Außerdem hat in C # null nicht wirklich eine numerische Entsprechung. Verweise in C # sind nicht dasselbe wie Zeiger und haben semantisch keine zugeordnete Speicheradresse. null bedeutet einfach, dass die Referenz nicht auf ein Objekt zeigt, und die interne Repräsentation null referenz ist ein Implementierungsdetail.

    
Sean U 25.01.2012 19:02
quelle
3

Es muss zuweisbar sein - selbst wenn es scheint, dass es "die gleiche Null" ist und es keine Rolle spielen sollte, behält der Compiler den Typ bei. Ein Vorteil davon ist das Auflösen von Überladungen:

%Vor%     
JimmiTh 25.01.2012 18:50
quelle
2

vielleicht object x = (string) null; das könnte funktionieren, aber warum sollten Sie?

weil ein Objekt eine Zeichenkette halten kann, aber eine Zeichenkette ein Objekt nicht halten kann

Zeichenfolge wird von Objekt geerbt, nicht umgekehrt.

    
SynerCoder 25.01.2012 18:46
quelle
0

Sie können jeder Variablen des Referenztyps null zuweisen, ohne dass etwas ausgegeben wird:

%Vor%     
Mithrandir 25.01.2012 18:47
quelle
0

Jede Klasse hat eine Liste von Definitionen für:

%Vor%

Objekt ist ein generischer Typ, weil jede Klasse von ihr erbt, aber nicht anders. Diese Definitionen sind nicht für jede Klasse gleich, daher kann Ihr Compiler entscheiden, welche Typen Sie einander zuordnen / zuweisen können.

Dann tust du: string x = (object)null;

Der Compiler kümmert sich nicht um den Wert, den Sie Ihrem x an erster Stelle zuweisen wollen, aber es überprüft die Typdefinitionen von string und lässt Sie nicht Ihr eigenes Bein erschießen und erzeugt einen Fehler, weil es so ist ein Typkonflikt.

    
0xbadc0de 25.01.2012 19:04
quelle