Laden...

Boxing/Unboxing: Es wird in Büchern immer erwähnt, aber welchen Vorteil bringt es mit sich?

Erstellt von nicky vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.997 Views
N
nicky Themenstarter:in
232 Beiträge seit 2011
vor 12 Jahren
Boxing/Unboxing: Es wird in Büchern immer erwähnt, aber welchen Vorteil bringt es mit sich?

Hi Leute,

ich komme aus dem Pascal/Delphi Bereich und möchte mich ein wenig in Richtung .NET orientieren. Meine Entscheidung viel auf C# 😃

Beim durchgehen der Grundlagen bin ich auf "Boxing / Unboxing" gestoßen. Wie es funktioniert habe ich verstanden deswegen geht meine Frage nicht unbedingt auf die Grundlage an sich ein 😃

Welchen Vorteil habe ich wenn ich eine Integer Varibale (Wertetyp) in eine Object Variable (Referenztyp) "konvertiere"?

Folgenden Code kann man so oder ähnlich auf nahezu jeder Grundlagen Seite für C# sehen:

            int i = 321;
            object o = i; //boxed

Kann mir jemand erklären wann man davon Gebrauch macht ? Vielleicht mit einem kleinen Beispiel ?

Ciao, nicky

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo nicky, willkommen im Forum,

i.d.R. veruscht man Boxing/Unboxing zu vermeiden. Seit .net 2.0 gibt es Generika (engl.: Generics) und somit braucht man das (fast) nie, da immer stark typisiert gearbeitet werden kann bzw. sollte dies immer versucht werden.
Deshalb sollten z.B. auch die generischen Listen-Klassen aus System.Collections.Generic verwendet werden und nicht die alten wie ArrayList. Bei den alten war boxing/unboxing notwendig.

In den Bücher wird deshalb noch aufgeführt, da es einfach zu Grundlagen gehört.

Ein konkreter, aber fortgeschrittener, Anwendungsfall ist das Verhindern von "torn writes" bei asynchronen Vorgängen. D.h. die CLR bzw. das Speichermodell von .net stellt nur sicher dass Werttypen kleiner 32 bit auf einem 32 bit-System atomar geschrieben werden. Für 64 bit analog. Durch Boxing wird ein Referenztyp daraus und der wird garantiert immer atomar geschrieben.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

N
nicky Themenstarter:in
232 Beiträge seit 2011
vor 12 Jahren

Hey, danke für deine schnelle Antwort. Ich würde ich mich in C# sowie in Delphi nicht als "fortgeschritten" bezeichnen deswegen kann ich deine Antwort leider nicht deuten.

Hmm, ich finds einfach nur Ärgerlich das in der Literatur immer erklärt wird wie Boxing und Unboxing funktioniert, jedoch wird kein sinnvolles Beispiel zur Verwendung gezeigt. Naja ok, kann ich scheinbar erstmal nur so hinnehmen 😃

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo nicky,

jedoch wird kein sinnvolles Beispiel zur Verwendung gezeigt.

weils eben seite der Einführung von den Generics kein sinnvolles (mehr) gibt.

Es gibt nur "Sonderfälle": den von oben und vllt. noch eher gebräuchlich wenn mit Reflection gearbeitet wird. Aber sonst nie.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

N
nicky Themenstarter:in
232 Beiträge seit 2011
vor 12 Jahren

Dann macht das Lehren auch keinen Sinn 😃

"Mal was davon gehört zu haben, ohne das man einen Anwendungsfall kennt kann nicht das Ziel sein" ...

In meinem C# Buch 2008 findet man das Thema unter "Grundlagen", jedoch ohne Bsp.

Hinweis von herbivore vor 12 Jahren

Dran, dass ein Feature, das in .NET 1.x sehr wichtig war, aber mit der Einführung von Generics in .NET 2.0 fast gänzlich an Bedeutung verloren hat, ist doch nicht viel zu verstehen. Ebenso, dass es deshalb so gut wie keine sinnvollen Beispiele mehr gibt.

Davon gehört haben sollte man trotzdem mal, weil es gerade in bestehendem Code natürlich immer noch vorkommen, dass ein Werttyp einer Variable von Typ Object zugewiesen bzw. ein Werttyp an einen Parameter vom Typ Object übergeben wird und natürlich auch der umgekehrte Weg, bei dem die Variable bzw. der Parameter wieder auf den Ursprungstyp gecastet wird.

Dem trägt die Erwähnung in deinem Buch Rechnung. Dramatisch und unverständlich wird das ganze erst, wenn man anfängt, viel Lärm um nichts zu machen.

C
1.214 Beiträge seit 2006
vor 12 Jahren

"Mal was davon gehört zu haben, ohne das man einen Anwendungsfall kennt kann nicht das Ziel sein" ...

Das ist die falsche Einstellung, zumindest in dem Fall. Die Grundlagen musst du absolut sicher beherrschen, sonst hast du keine Ahnung, was du machst/was passiert. Und grad Boxing/Unboxing ist etwas, was doch recht häufig vorkommt, auch wenns dafür mittlerweile wenige sinnvolle Beispiele gibt. Eins kann ich dir aber nennen:

Dictionary<string, object>. So ein Konstrukt sieht man dann doch relativ häufig, um generische Eigenschaften zu speichern. Wenn du jetzt als Wert sagen wir eine Zahl speicherst, kommt es boxing/unboxing.

N
nicky Themenstarter:in
232 Beiträge seit 2011
vor 12 Jahren

Natürlich ist das die falsche Einstellung. Deswegen bin ich auch so hartnäckig 😃

Also kommt Boxing / Unboxing nur vor wenn die Methode ein Objekt Datentyp erwartet. Naja ich werde wohl im Laufe der Zeit sehen ob und wie ich es einsetze... 😃 Im Moment kann ich die Idee nicht auf meine Projekte übertragen.

C
1.214 Beiträge seit 2006
vor 12 Jahren

Das ist keine Idee, und das kannst du nicht einsetzen. Das passiert immer, wenn du einem Object einen Valuetype zuweist. Das passiert einfach und das musst du wissen. Wobei, wenn du so willst, dann musst du Unboxing selber einsetzen, wenn du aus dem Object den Wert wieder rauskriegen willst, indem du castest.

5.742 Beiträge seit 2007
vor 12 Jahren

Um es ein wenig anders zu formulieren:
Boxing ermöglicht, dass wirklich alle FCL-Typen, auch Wertetypen (wie int etc.) von object erben und sich ohne Zusatzcode auch nach object konvertieren lassen.

In der Praxis merkt man eigentlich gar nicht, wenn man es anwendet; dass C# Autoboxing unterstützt, merkt man erst, wenn man eine Sprache verwendet, die das nicht unterstützt, z.B. Java.
Dort ist es folgendermaßen:


int i = 5;
Object obj = i; //Fehler
obj = new Integer(i); //Integer ist eine spezielle Klasse, um manuelles Boxing zu ermöglichen; ist *kein* Synonym für int

//während du in C# problemlos schreiben kannst:
int i = 5;
object obj = i;

In ein Grundlagenbuch gehört sowas aber eher nicht; IMHO erwartet man sogar, dass Boxing vorhanden ist 😉

C
1.214 Beiträge seit 2006
vor 12 Jahren

In der Praxis merkt man eigentlich gar nicht, wenn man es anwendet; dass C# Autoboxing unterstützt, merkt man erst, wenn man eine Sprache verwendet, die das nicht unterstützt, z.B. Java.

Java unterstützt seit Version 5 ebenfalls Autoboxing. Nur funktioniert es immer noch nicht so "schön" wie in C#. (Ich finde sowas in Java generell ziemlich verkramft, aber das ist ein anderes Thema...

1.130 Beiträge seit 2007
vor 12 Jahren

Man braucht boxing für virtuelle methoden.
Z.B. folgendes:


string.Format("{0} hat den TypeCode {1}", 1, 1.GetTypeCode());

Quizfrage: Wieviele boxings sind hier versteckt?

Abgesehen von obigem einsatz hat boxing noch ein paar besonderheiten, z.B. folgendes (siehe using Statement (C# Reference)):


Dictionary<string,string> dict=...
using(var enumerator=dict.GetEnumerator())
{
   ...
}

Außerdem sind geboxte objekte nicht zwangsläufig immutable und man kann sogar mit ihnen arbeiten:


interface Interface
{
	string Foo{get;set;}
}
	
struct Struct:Interface
{
	public string Foo{get;set;}
}

Interface box=new Struct{Foo="wert1"};
Interface var1=box;
Struct var2=(Struct)box;
box.Foo="wert2";
Console.WriteLine(string.Format("{0} {1}",var1.Foo,var2.Foo));
Hinweis von herbivore vor 12 Jahren

Mit immutable hat das nichts zu tun. Ein Objekt ist immutable, wenn es es keine (öffentlichen) Properties, Methoden und andere Member gibt, über die es geändert werden kann. Dein Struct ist mutable (=änderbar), weil es eine ändernde Property gibt, ganz egal ob man Boxing benutzt oder nicht.

Dein Beispiel zeigt allerdings, dass es möglich ist, mehrere Referenzen auf ein geboxtes Objekt zu setzen und - weil man dafür einen Interfaces Typ und nicht den Typ Object verwendet - die ändernde Property auch tatsächlich zu benutzen.

Dass das mit Interfaces geht, ist schon was besonderes, denn würde man den Typ Object benutzen, könnte man die Property nicht benutzen, weil sie nicht in Object definiert ist. Würde man auf den dynamischen Typ des Objekts zurückcasten, käme man aber auch nicht weiter, weil dann unboxing stattfinden würde.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!