Scelta tra classi e structChoosing Between Class and Struct

Una delle decisioni di progettazione di base ogni volto di progettazione Framework è se progettare un tipo come classe (un tipo di riferimento) o come struct (tipo valore).One of the basic design decisions every framework designer faces is whether to design a type as a class (a reference type) or as a struct (a value type). Una migliore comprensione delle differenze nel comportamento dei tipi di riferimento e dei tipi di valore è essenziale per la scelta.Good understanding of the differences in the behavior of reference types and value types is crucial in making this choice.

La prima differenza tra i tipi di riferimento e i tipi di valore che consideriamo è che i tipi di riferimento vengono allocati nell'heap e sottoposti a Garbage Collection, mentre i tipi di valore vengono allocati nello stack o inline in che contengono tipi e deallocati quando lo stack viene rimosso o quando il tipo contenitore viene deallocato.The first difference between reference types and value types we will consider is that reference types are allocated on the heap and garbage-collected, whereas value types are allocated either on the stack or inline in containing types and deallocated when the stack unwinds or when their containing type gets deallocated. Pertanto, le allocazioni e le deallocazioni di tipi di valore sono in genere più convenienti rispetto alle allocazioni e alle deallocazioni dei tipi di riferimento.Therefore, allocations and deallocations of value types are in general cheaper than allocations and deallocations of reference types.

Successivamente, le matrici di tipi di riferimento vengono allocate fuori riga, ovvero gli elementi della matrice sono solo riferimenti a istanze del tipo di riferimento che risiedono nell'heap.Next, arrays of reference types are allocated out-of-line, meaning the array elements are just references to instances of the reference type residing on the heap. Le matrici di tipi di valore vengono allocate inline, vale a dire che gli elementi della matrice sono le istanze effettive del tipo di valore.Value type arrays are allocated inline, meaning that the array elements are the actual instances of the value type. Pertanto, le allocazioni e le deallocazioni di matrici di tipi di valore sono molto più convenienti delle allocazioni e delle deallocazioni di matrici di tipi di riferimento.Therefore, allocations and deallocations of value type arrays are much cheaper than allocations and deallocations of reference type arrays. Inoltre, nella maggior parte dei casi, le matrici di tipi di valore presentano una maggiore località di riferimento.In addition, in a majority of cases value type arrays exhibit much better locality of reference.

La differenza successiva riguarda l'utilizzo della memoria.The next difference is related to memory usage. Quando si esegue il cast a un tipo di riferimento o a una delle interfacce implementate, i tipi di valore ottengono il Boxing.Value types get boxed when cast to a reference type or one of the interfaces they implement. Ottengono unboxed quando viene eseguito il cast al tipo di valore.They get unboxed when cast back to the value type. Poiché le caselle sono oggetti allocati nell'heap e vengono sottoposti a Garbage Collection, un numero eccessivo di operazioni di Boxing e unboxing può avere un impatto negativo sull'heap, il Garbage Collector e infine le prestazioni dell'applicazione.Because boxes are objects that are allocated on the heap and are garbage-collected, too much boxing and unboxing can have a negative impact on the heap, the garbage collector, and ultimately the performance of the application. Al contrario, non viene eseguita la conversione boxing in quanto viene eseguito il cast di tipi di riferimento.In contrast, no such boxing occurs as reference types are cast. Per ulteriori informazioni, vedere Boxing e unboxing.(For more information, see Boxing and Unboxing).

Le assegnazioni dei tipi di riferimento, quindi, copiano il riferimento, mentre le assegnazioni dei tipi di valore copiano l'intero valore.Next, reference type assignments copy the reference, whereas value type assignments copy the entire value. Pertanto, le assegnazioni di tipi di riferimento di grandi dimensioni sono più convenienti rispetto alle assegnazioni di tipi di valore di grandi dimensioni.Therefore, assignments of large reference types are cheaper than assignments of large value types.

Infine, i tipi di riferimento vengono passati per riferimento, mentre i tipi di valore vengono passati per valore.Finally, reference types are passed by reference, whereas value types are passed by value. Le modifiche apportate a un'istanza di un tipo riferimento influiscono su tutti i riferimenti che puntano all'istanza.Changes to an instance of a reference type affect all references pointing to the instance. Le istanze del tipo di valore vengono copiate quando vengono passate per valore.Value type instances are copied when they are passed by value. Quando viene modificata un'istanza di un tipo di valore, ovviamente non influisce sulle copie.When an instance of a value type is changed, it of course does not affect any of its copies. Poiché le copie non vengono create in modo esplicito dall'utente, ma vengono create in modo implicito quando gli argomenti vengono passati o vengono restituiti valori restituiti, i tipi di valore che possono essere modificati possono generare confusione per molti utenti.Because the copies are not created explicitly by the user but are implicitly created when arguments are passed or return values are returned, value types that can be changed can be confusing to many users. Pertanto, i tipi di valore non devono essere modificabili.Therefore, value types should be immutable.

Come regola generale, la maggior parte dei tipi in un Framework deve essere una classe.As a rule of thumb, the majority of types in a framework should be classes. In alcune situazioni, tuttavia, le caratteristiche di un tipo di valore rendono più appropriato utilizzare gli struct.There are, however, some situations in which the characteristics of a value type make it more appropriate to use structs.

✔️ CONSIGLIABILE definire uno struct anziché una classe se le istanze del tipo sono di dimensioni ridotte e di breve durata o sono comunemente incorporate in altri oggetti.✔️ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

❌ EVITARE di definire uno struct, a meno che il tipo non abbia tutte le caratteristiche seguenti:❌ AVOID defining a struct unless the type has all of the following characteristics:

  • Rappresenta logicamente un singolo valore, simile ai tipi primitivi ( int , double e così via).It logically represents a single value, similar to primitive types (int, double, etc.).

  • Ha una dimensione di istanza inferiore a 16 byte.It has an instance size under 16 bytes.

  • Non è modificabile.It is immutable.

  • Non sarà necessario eseguire la conversione boxing di frequente.It will not have to be boxed frequently.

In tutti gli altri casi, è necessario definire i tipi come classi.In all other cases, you should define your types as classes.

Parti © 2005, 2009 Microsoft Corporation. Tutti i diritti riservati.Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

Ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2a edizione di Krzysztof Cwalina and Brad Abrams, pubblicato il 22 ottobre 2008 da Addison-Wesley Professional nella collana Microsoft Windows Development Series.Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.

Vedere ancheSee also