frage zu arrays
-
Ich verstehe irgendwie die Problematik nicht ganz. Warum sollte man ein char[] in ein object[] konvertieren können? Dass es nicht geht, hat doch nichts mit Referenztypen und Werttypen zu tun, sondern einfach nur damit, dass ein char[] von System.Array erbt und von daher auch nur in ein object zu konvertieren ist. In ein object[] könnte man nur die Arrayelemente konvertieren, aber an die kommt man nicht heran, da sie in der Klasse zu stark eingekapselt sind und von daher nur einzeln mit dem []-Operator bekommen werden können.
-
Optimizer schrieb:
Was du hier zusammenhackst ist ein typunsicherer "reinterpret_cast". Das ist keine Konvertierung. Wenn du irgendwelche Bytes hast (z.B. ein char[]), dann kannst du es auf die Weise nicht zu einem Object[] machen, weil du dann die chars als Referenzen interpretieren musst und auf was sollen die denn bitte zeigen, wenn du nicht die entsprechenden Objekte allokierst?
Dann hast aber bis jetzt zu 99% typunsichere Programme erstellt, denn genauso
sieht ein Zuweisung von einem abgeleiteten Typ auf einen Basis-Typ aus ..Wenn es typunsicher wäre, würde es ja wohl ne Exception werfen und schon
gar nicht, das gewünschte Ergebniss liefern. Wie wenn es Zufall wäre, das
es klappt ..[edit]
Das wär ja im Prinzip das selbe wie wenn du sagen würdest, ein Cast
von int32 nach int64 ist typunsicher, da möglicherweise die restlichen
32 Bit undefiniert sind. Wir alle wissen, dass dem nicht der Fall ist,
weil die CLR weiß was zu tun ist. Könnte doch genauso gut sein, dass die
CLR weiß was zu tun ist, wenn ich eben ein Array von Wertetypen einem
Array von objects zuweise.
[/edit]Ich versuch einfach nochmal den Thread hier zusammenzufassen ..
Ein Cast von char[] nach object[] ist in C# nicht erlaubt. Deine Begründung
baute auf die Unterschiede zwischen Referenztypen und Wertetypen auf. Wenn
es allerdings wirklich davon abhängen würde, müsste die CLR bei so nem Cast
ja bereits schreien. Von ihr hängt ja letztendlich ab, was erlaubt ist und
was nicht, was typsicher ist und was nicht, etc .. Mit meinem Beispiel
"dahingehackt" in IL wollte ich aber nur beweisen, dass die CLR eben nicht
aufschreit, sondern nur der C# Compiler. Somit kann der Unterschied zwischen
Referenz- und Wertetyp nicht der Grund sein, warum der Cast nicht erlaubt ist.Hoffentlich konnte ich jetzt meinen Gedankengan verdeutlichen ..
masterofx32 schrieb:
Ich verstehe irgendwie die Problematik nicht ganz. Warum sollte man ein char[] in ein object[] konvertieren können? Dass es nicht geht, hat doch nichts mit Referenztypen und Werttypen zu tun, sondern einfach nur damit, dass ein char[] von System.Array erbt und von daher auch nur in ein object zu konvertieren ist. In ein object[] könnte man nur die Arrayelemente konvertieren, aber an die kommt man nicht heran, da sie in der Klasse zu stark eingekapselt sind und von daher nur einzeln mit dem []-Operator bekommen werden können.
...
string[] strArr = { "Hello", "World" }; object[] objArr = strArr;
-
Hmm, OK, mein Argumentevorrat ist leer. Ich klinke mich dann mal aus der Diskussione aus - tschühüs
-
@Tankian:
Du kapierst es nicht, dass die Repräsentation anders ist. char[] -> object[] ist ein völlig anderer Fall als class Foo[] -> object[]. Wenn du die Referenz von char[] auf object[] ändern könntest, würden die chars als Referenzen interpretiert werden und das geht halt einfach nicht, weil die dann irgendwo ins Nirvana zeigen. Wenn du keine Objekte (also geboxte chars) erstellst, was soll denn dann am Ende rauskommen?
Dass class Foo[] -> Object geht, ist ja sofort einsichtig: Der Elementtyp des Arrays ist immer noch eine Referenz. Das kannst du aber für ein char[] nicht machen, du hast danach nichts mehr, was irgendwie noch brauchbar ist. Und natürlich wirst du dann auch irgendwann deine AccessViolationException kriegen, auf die du schon sehnsüchtig wartest.Was glaubst du denn, hast du mir mit deinem Code gezeigt? Gar nichts. Absolut überhaupt gar nichts. Weil du was völlig anderes gemacht hast, ich kann mir nicht mal einen Grund vorstellen, warum du den überhaupt gebracht hast. Mit dem Thread hatte das jedenfalls nichts zu tun.
Dann hast aber bis jetzt zu 99% typunsichere Programme erstellt, denn genauso
sieht ein Zuweisung von einem abgeleiteten Typ auf einen Basis-Typ aus ..Völliger Unfug. Hier änderst du nur den statischen typ einer Referenz und referenzierst anschließend sogar noch das selbe Objekt. Diesen Cast gibt es nicht mal mehr im CIL Code. Für char[] -> object[] müsstest du etwas, was nicht mal ne Referenz ist, als Referenz interpretieren, was dann auf irgendwas (und was?) zeigt und das Verweisziel gibt es nicht mal. Mir ist nicht einsichtig, warum du da einen Zusammenhang siehst.
Somit kann der Unterschied zwischen
Referenz- und Wertetyp nicht der Grund sein, warum der Cast nicht erlaubt ist.Ja sicher. *kopfschüttel*
Einigen wir uns doch einfach darauf: Du postest hier Code in einer .Net Sprache deiner Wahl, der einfach mal schnell ein char[] in ein Object[] umwandelt, also ohne ein Object[] anzulegen und die einzelnen chars auszulesen und geboxed ins Object[] abzulegen. Und bitte keinen anderen Code mehr...
-
Überleg dir das doch mal anhand von C++ (standard) Code:
Du hast ein char[]. Und das willst du in ein Object*[] casten.Pseudocode:
char a[10]; Object* b[10] = reinterpret_cast<Object*[]>(a);
Was glaubst du, wird das? Das wird undefiniertes Verhalten hoch 10. Das fängt ja schon damit an, dass sizeof(char) nicht unbedingt sizeof(Object*) ist.
-
Optimizer schrieb:
@Tankian:
Du kapierst es nicht, dass die Repräsentation anders ist. char[] -> object[] ist ein völlig anderer Fall als class Foo[] -> object[].Natürlich ist die Represäntation nach aussen hin anders. Aber intern
könnte der CLR doch vllt sogar egal sein ob es ein Wertetyp oder Referenztyp
ist. Vllt ist intern ein Wertetyp sogar nur ein Referenztyp, etc .. Sind zwar
alles Mutmaßungen, aber damit sollte klar werden, dass man eben nicht mit
absolut 100% Sicherheit sagen kann, was die CLR intern alles erledigt.Woher willst du wissen, dass die CLR eine Konvertierung von char[] nach object[]
nicht eh wieder so implementiert wie es bereits vorgeschlagen wurde (Boxen in
einer Schleife). Wenn du mir das zeigen kannst, durch irgendnen MSDN-Artikel,
Beispielcode, etc.. dann ist der Code denn ich gepostet habe wirklich typunsicher.
Ansonsten funktioniert er prima ..Optimizer schrieb:
Was glaubst du denn, hast du mir mit deinem Code gezeigt? Gar nichts. Absolut überhaupt gar nichts. Weil du was völlig anderes gemacht hast, ich kann mir nicht mal einen Grund vorstellen, warum du den überhaupt gebracht hast. Mit dem Thread hatte das jedenfalls nichts zu tun.
Der Ausgangscode in C#:
int[] intArr = { ... }; // ob char oder int is ja egal .. object[] objArr = intArr; // nicht gültig ..
Nun mein IL-Code wieder zurück in C#:
int[] intArr = new int[3]; intArr[0] = 3; intArr[1] = 5; intArr[2] = 7; object[] objArr = intArr; // in IL eben erlaubt .. // unwichtiger Rest ...
Die restlichen Aufrufe von Console.WriteLine() waren ja nur für die Ausgabe
zuständig, damit ich zeigen konnte, dass auch wirklich 3, 5 und 7 in objArr
stehen.Jetzt würde ich aber gerne wissen, inwiefern
mein Code am Thema vorbeiging ..Optimizer schrieb:
Überleg dir das doch mal anhand von C++ (standard) Code:
Du hast ein char[]. Und das willst du in ein Object*[] casten.Pseudocode:
char a[10]; Object* b[10] = reinterpret_cast<Object*[]>(a);
Das sowas undefiniert ist, ist mir klar. Ich versteh auch, dass
eine Zuweisung von einem Wertetyp auf einen Referenztyp ohne
Boxing undefiniert sein müsste. Allerdings wie bereits gesagt,
wird das Boxing bei Arrays vielleicht wieder anders erledigt.
(oder eben noch "automatischer", so das man eben selbst in IL
Code nichts mehr davon sieht ..)Falls immernoch unklar sein sollte, was ich meine, bzw. du
immernoch glaubst ich bin am Thema vorbeigegangen, dann frag
ich dich eben mal:Warum funktioniert mein IL-Code? Erklär mir das bitte, aber
komm erst mit Behauptungen wie typunsicher, etc.. wenn du
dafür auch halbwegs handfeste Beweise hast (eben Artikel, etc..).grüße
-
Tankian schrieb:
Natürlich ist die Represäntation nach aussen hin anders. Aber intern
könnte der CLR doch vllt sogar egal sein ob es ein Wertetyp oder Referenztyp
ist. Vllt ist intern ein Wertetyp sogar nur ein Referenztyp, etc .. Sind zwar
alles Mutmaßungen, aber damit sollte klar werden, dass man eben nicht mit
absolut 100% Sicherheit sagen kann, was die CLR intern alles erledigt.Nein, Value Types sind nicht intern Reference Types.
Woher willst du wissen, dass die CLR eine Konvertierung von char[] nach object[]
nicht eh wieder so implementiert wie es bereits vorgeschlagen wurde (Boxen in
einer Schleife).Du schreibst doch den CIL Code selber. Tust du dort sowas? Nein? Dann ist es auch nicht drin.
Der Ausgangscode in C#:
int[] intArr = { ... }; // ob char oder int is ja egal ..
Die restlichen Aufrufe von Console.WriteLine() waren ja nur für die Ausgabe
zuständig, damit ich zeigen konnte, dass auch wirklich 3, 5 und 7 in objArr
stehen.Jetzt würde ich aber gerne wissen, inwiefern
mein Code am Thema vorbeiging ..Nein. Ob char oder int ist nicht egal, weil sizeof(char) != sizeof(int).
Ja geil. Da stehen wirklich 3, 5 und 7 drin. SUPER! Caste das jetzt bitte in ein Object[] und liefer mir die Objekte, die das Array dann in referenziert.Checkst du's nicht? Oder bist du uneinsichtig? Wie auch immer, für mich ist das hier beendet, ist doch lächerlich. Du gibst ja selber zu, dass der C++ Code undefiniertes Verhalten hätte. Aber wie zum Beweis, dass es in .Net geht zeigst du mir, dass 3, 5 und 7 drin stehen, also dein Object* den Wert 3 und 5 und 7 hat. Das damit referenzierte Objekt, welches es gar nicht gibt, interessiert dich nicht und dass das Array als Object[] völlig nutzlos ist, was ich dir die ganze Zeit sage, interessiert dich auch nicht. Stattdessen zeigst du mir, dass wenn du es nicht änderst immer noch das Bitmuster von 3, 5 und 7 drin ist.
Wenn das alles ist, was du mir zu sagen hast, enttäusche ich dich nur ungern, aber das hätte ich fast auch vermutet.</Diskussion>
-
Nein. Ob char oder int ist nicht egal, weil sizeof(char) != sizeof(int).
Ich hab meinen IL-Code bereits mit char, int und double getestet. Jedesmal
hat er funktioniert. Hast noch einen Vorschlag, mit was ich testen soll ?Du schreibst doch den CIL Code selber. Tust du dort sowas? Nein? Dann ist es auch nicht drin.
Na und, ich schreibe ja auch nicht in den IL-Code, dass die Variable in das
Register kommt, jene Variable in jenes Register und der CPU dann mitteile
zu addieren ..
-
Tankian schrieb:
Ich hab meinen IL-Code bereits mit char, int und double getestet. Jedesmal
hat er funktioniert. Hast noch einen Vorschlag, mit was ich testen soll ?Sag ich doch die ganze Zeit. Mach ein char[] zu nem object[] und benutze die Objekte darin dann, z.B. alle serialisieren und in Datei schreiben.
-
Optimizer schrieb:
Mach ein char[] zu nem object[] und benutze die Objekte darin dann, z.B. alle serialisieren und in Datei schreiben.
Hmm ..
Wahrscheinlich wirds wohl doch typsicher sein, denn kaun greif ich von
C# aus auf so ein object[] Array zu, bekomm ich ne ExecutingEngineException.
Wobei es eben nach wie vor klappt, wenn ich alles in IL code. Wahrscheinlich
ist IL doch etwas freizügiger mit den Casts, als es sein sollte ..Nur wunderts mich immernoch, dass es in IL
mit char, int und decimal klappt ..Naja, tut mir leid für deine Zeit ..