Garbage collection per wrapper ValueType
-
03-07-2019 - |
Domanda
Citando dal Link MSDN per la classe ValueType
Nei casi in cui è necessario che un tipo di valore si comporti come un oggetto, un wrapper che fa sembrare il tipo di valore simile a un oggetto di riferimento viene allocato sull'heap e il valore del tipo di valore viene copiato in esso. Il wrapper è contrassegnato in modo che il sistema sappia che contiene un tipo di valore.
Ciò significa che quando codice come " integerVariable.ToString (); " un oggetto wrapper creato consente di utilizzare questo metodo e allo stesso modo tutti gli altri metodi di System.Object.
Questa comprensione è corretta?
In che modo questi oggetti sono diversi dagli oggetti "normali"?
La Garbage Collection è diversa per tale oggetto? Se sì, come?
Grazie in anticipo.
Soluzione
Il wrapper è una "scatola"; per quanto riguarda la raccolta dei rifiuti - non esiste alcuna differenza nessuna per quanto riguarda il raccoglitore di rifiuti. Una scatola viene raccolta esattamente con le stesse regole e lo stesso trattamento di qualsiasi altro oggetto.
tuttavia, se un tipo di valore sovrascrive un metodo (come ToString ()
), non è necessario inserirlo nella casella per chiamare il metodo. Quindi, i tipi di valore dovrebbero (come una questione di routine) sovrascrivere il maggior numero possibile di metodi oggetto
;-p
Puoi vedere la differenza in IL (tramite riflettore), quindi per C #:
static int GetInteger() {return 123;}
static string TestToString() {
int i = GetInteger(); // to prove no cheating
return i.ToString();
}
static Type TestGetType() {
int i = GetInteger(); // to prove no cheating
return i.GetType();
}
Abbiamo IL:
.method private hidebysig static string TestToString() cil managed
{
.maxstack 1
.locals init (
[0] int32 i)
L_0000: call int32 Program::GetInteger()
L_0005: stloc.0
L_0006: ldloca.s i
L_0008: call instance string [mscorlib]System.Int32::ToString()
L_000d: ret
}
.method private hidebysig static class [mscorlib]System.Type TestGetType() cil managed
{
.maxstack 1
.locals init (
[0] int32 i)
L_0000: call int32 Program::GetInteger()
L_0005: stloc.0
L_0006: ldloc.0
L_0007: box int32
L_000c: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0011: ret
}
Nota che ToString ()
non comporta una casella, ma GetType ()
lo fa su L_0007
(poiché non lo è ( impossibile) sovrascritto)
Altri suggerimenti
Sì, la comprensione è corretta.
Questi oggetti non sono diversi dagli oggetti "normali" nel CLR.
Dato che questi oggetti (chiamati anche 'box' perché avvolgono i tipi di valore) sono esattamente come qualsiasi altro oggetto, anche il Garbage Collector è lo stesso.