Frage

  

Es gibt Fälle, wenn eine Instanz eines   Werttyp muss als ein behandelt werden   Instanz eines Referenztyp. Für   Situationen wie dieser, ein Werttyp   kann beispielsweise in ein umgewandeltes werden   Referenztyp weise durch ein   Prozess namens Boxen. Wenn ein Wert   Typ-Instanz ist eingerahmt, die Lagerung ist,   auf dem Heap zugewiesen und die   Instanz Wert wird in das kopiert   Platz. Ein Hinweis auf diese Speicher ist   auf den Stapel gelegt. Der Box-Wert   ist ein Ziel, ein Referenztyp, der   enthält den Inhalt des Wertes   Typ-Instanz.

     

Legendes .NET Common Type System

Wikipedia gibt es ein Beispiel für Java. Aber in C #, was sind einige Fälle, in denen man hätte einen Werttyp boxen? Oder wäre eine bessere / ähnliche Frage sein, warum sollte man einen Werttyp auf dem Heap gespeichert werden soll (boxed), anstatt auf dem Stack?

War es hilfreich?

Lösung

Im Allgemeinen Sie in der Regel wollen Ihre Werttypen vermeiden Boxen.

Es gibt jedoch seltene Vorkommen, wo dies sinnvoll ist. Wenn Sie das 1.1 Framework zum Ziel benötigen, zum Beispiel, werden Sie keinen Zugriff auf die generischen Sammlungen haben. Jede Nutzung der Sammlungen in .NET 1.1 würde Ihren Werttyp als System.Object erfordert die Behandlung, die Boxen / Unboxing verursacht.

Es gibt immer noch Fälle, für diese in .NET 2.0+ nützlich zu sein. Jedes Mal, wenn sich die Tatsache zunutze machen wollen, dass alle Arten, einschließlich Werttypen können direkt als Objekt behandelt werden, müssen Sie möglicherweise Boxen / Unboxing verwenden. Dies kann manchmal nützlich sein, da es Ihnen erlaubt, jede Art in einer Sammlung zu speichern (durch Objekt anstelle von T in einer generischen Sammlung verwendet wird), aber im Allgemeinen ist es besser, dies zu vermeiden, wie Sie Typsicherheit sind zu verlieren. Der einzige Fall, in dem Boxen häufig auftritt, obwohl, wenn Sie verwenden Reflection -. Viele der Anrufe in der Reflexion wird Boxen / Unboxing erfordern, wenn sie mit Werttypen arbeiten, da der Typ nicht im Voraus bekannt ist

Andere Tipps

Es gibt so gut wie nie einen guten Grund, absichtlich einen Werttyp boxen. Fast immer der Grund, einen Werttyp zu boxen ist es in irgendeiner Sammlung zu speichern, die nicht bewusst ist, geben. Die alte Arraylist zum Beispiel ist eine Sammlung von Objekten, die Referenztypen sind. Der einzige Weg, zu sammeln, zu sagen, ganze Zahlen sind, sie als Objekte Feld und gibt ihnen Arraylist.

Heute haben wir generische Sammlungen, so ist dies weniger ein Problem.

Boxen geschieht in der Regel automatisch in .NET, wenn sie müssen; oft, wenn Sie einen Wert Typen etwas übergeben, die einen Referenztyp erwartet. Ein gängiges Beispiel ist string.Format (). Wenn Sie primitive Werttypen an diese Methode übergeben, werden sie als Teil des Aufrufs eingerahmt. Also:

int x = 10;
string s = string.Format( "The value of x is {0}", x ); // x is boxed here

Dies zeigt ein einfaches Szenario, in dem ein Werttyp (x) eingerahmt wird automatisch an eine Methode übergeben werden, die ein Objekt erwartet. Normalerweise wollen Sie Boxen Werttypen, wenn möglich ... aber in einigen Fällen zu vermeiden, ist es sehr nützlich.

Auf einer interessanten Seite, wenn Sie Generika in .NET, Werttypen sind eingerahmt nicht, wenn sie als Parameter oder Mitglieder des Typs verwendet. Das macht Generika effizienter als ältere C # -Code (wie Arraylist), die alles als {Objekt} behandeln Typ Agnostiker sein. Dies fügt einen weiteren Grund generische Sammlungen zu verwenden, wie List<T> oder Dictionary<T,K> über ArrayList oder Hashtable.

Ich würde Ihnen 2 schönen Artikel von Eric Lippert empfehlen

http : //blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

Hier ist das Zitat, dass ich 100% stimmen

  

Mit dem Stapel für Einheimische Wert   Typ ist nur eine Optimierung, die das   CLR führt in Ihrem Namen.   Die entsprechende Funktion von Werttypen ist   dass sie die Semantik des Seins   von Wert kopiert, nicht, dass manchmal   ihre Freigabe kann optimiert werden durch   die Laufzeit.

In 99% Anwendungen Entwickler sollten über nicht kümmern, warum Werttypen sind in Stapel und nicht in dem Heap und welche Leistungssteigerung konnten wir hier haben. Juts im Sinne hat, sehr einfache Regeln:

  1. Vermeiden Boxen / Unboxing, wenn sie nicht erforderlich, verwenden Generika Sammlungen. Die meisten Probleme treten nicht, wenn Sie definieren Sie Ihre eigene Art, aber wenn man verwenden inproperly vorhandenen Typen (Definiert durch Microsoft oder Ihre collegues)
  2. Machen Sie Ihre Werttypen einfach. Wenn Sie eine Struktur haben, mit 10 bis 20 Felder, nehme ich an you'ld besser, eine Klasse erstellen. Stellen Sie sich vor, alle dass Felder jedes Mal kopiert werden wenn Sie geben es gelegentlich ein Funktion von Wert ...
  3. Ich glaube nicht, es ist sehr nützlich zu haben Werttypen mit Referenzart Felder im Inneren. Wie Struktur mit String und Objektfelder.
  4. definieren, welche Art Sie müssen je nach erforderliche Funktionalität, nicht auf dem es soll gespeichert werden. structs haben eingeschränkte Funktionalität im Vergleich zu Klassen, so dass, wenn struct kann nicht liefern die erforderliche Funktionalität, wie Standardkonstruktors definieren Klasse.
  5. Wenn etwas, was jeder durchführen kann Aktionen mit den Daten anderer Typen wird es in der Regel als eine definierte Klasse. Für structs Operationen mit verschiedene Arten definiert werden nur, wenn Sie einen Typen umwandeln können Ein weiterer. Sagen Sie bitte int hinzufügen können Doppel weil Sie int werfen können Doppel.
  6. Wenn etwas staatenlos sein sollte, ist es eine Klasse.
  7. Wenn Sie zögern, verwenden Referenztypen. : -)

Alle Regeln erlauben Ausnahmen in besonderen Fällen, aber versuchen Sie nicht zu über-optimize.

P. S. Ich traf einige ASP.NET-Entwickler mit 2-3 Jahren Erfahrung, die nicht den Unterschied zwischen Stack und Heap nicht kennt. :-( ich nicht mieten eine solche Person würde, wenn ich ein Interviewer bin, aber nicht, weil Boxen / Unboxing einen Engpass in einem ASP.NET-Sites könnte ich je gesehen habe.

Ich denke, ein gutes Beispiel für Boxen in c # tritt in den nicht-generischen Sammlungen wie Arraylist .

Ein Beispiel wäre, wenn ein Verfahren zur Herstellung eines Objektparameter und ein Werttyp nimmt muss übergeben werden.

Im Folgenden finden Sie einige Beispiele für Boxen / Unboxing

ArrayList ints = new ArrayList();
myInts.Add(1); // boxing
myInts.Add(2); // boxing

int myInt = (int)ints [0]; // unboxing

Console.Write("Value is {0}", myInt); // boxing

Eine der Situationen, in denen dies geschieht, ist zum Beispiel, wenn Sie Methode, die Parameter des Typs Objekts erwarten und Sie übergeben in einen der primitiven Typen, int zum Beispiel. Oder wenn Sie definieren Parameter als 'ref' vom Typ int.

Der Code

int x = 42;
Console.Writeline("The value of x is {0}", x );

eigentlich Boxen und unboxes weil Writeline tut ein int innen gegossen. Um dies zu vermeiden Sie tun können,

int x = 42;
Console.Writeline("The value of x is {0}", x.ToString());

Vorsicht vor subtiler Bugs!

Sie können Ihre eigenen Wertetypen, indem er erklärt Ihre eigene Art als struct erklären. Stellen Sie sich eine struct mit vielen Eigenschaften deklarieren und dann einige Instanzen innerhalb eines ArrayList setzen. Diese Boxen sie natürlich. Jetzt eine durch den [] Operator verweisen, es auf die Art des Gießens und eine Eigenschaft festgelegt. Sie haben soeben eine Eigenschaft auf Kopie gesetzt. Die in der ArrayList ist nach wie vor unverändert.

Aus diesem Grunde Werttypen müssen immer unveränderlich sein, das heißt alle Membervariablen machen readonly, so dass sie nur im Konstruktor festgelegt werden können, und hat keine änderbaren Typen als Mitglieder.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top