Escolher entre Classe e StructChoosing Between Class and Struct

Uma das decisões básicas de design que cada designer de estrutura enfrenta é se deve criar um tipo como uma classe (um tipo de referência) ou como uma struct (um tipo de valor).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). Uma boa compreensão das diferenças no comportamento dos tipos de referência e dos tipos de valor é crucial para fazer essa escolha.Good understanding of the differences in the behavior of reference types and value types is crucial in making this choice.

A primeira diferença entre os tipos de referência e os tipos de valor que consideraremos é que os tipos de referência são alocados no heap e no lixo coletado, enquanto os tipos de valor são alocados na pilha ou embutidos em tipos contendo e desalocados quando a pilha desenrola ou quando seu tipo recipiente é desalocado.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. Portanto, alocações e desalocações de tipos de valor são em geral mais baratas do que as alocações e desalocações de tipos de referência.Therefore, allocations and deallocations of value types are in general cheaper than allocations and deallocations of reference types.

Em seguida, as matrizes dos tipos de referência são alocadas fora de linha, o que significa que os elementos da matriz são apenas referências a instâncias do tipo de referência que residem no 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. Matrizes de tipo de valor são alocadas embutidas, o que significa que os elementos da matriz são as instâncias reais do tipo de valor.Value type arrays are allocated inline, meaning that the array elements are the actual instances of the value type. Portanto, alocações e desalocações de matrizes de tipo de valor são muito mais baratas do que as alocações e desalocações de matrizes de tipo de referência.Therefore, allocations and deallocations of value type arrays are much cheaper than allocations and deallocations of reference type arrays. Além disso, na maioria das vezes, as matrizes de tipo de valor apresentam uma localidade muito melhor de referência.In addition, in a majority of cases value type arrays exhibit much better locality of reference.

A próxima diferença está relacionada ao uso de memória.The next difference is related to memory usage. Os tipos de valor ficam na caixa quando são convertidos em um tipo de referência ou em uma das interfaces que implementam.Value types get boxed when cast to a reference type or one of the interfaces they implement. Eles ficam inativos ao converter de volta para o tipo de valor.They get unboxed when cast back to the value type. Como as caixas são objetos alocados no heap e são coletadas com lixo, muitas boxing e unboxing podem ter um impacto negativo sobre o heap, o coletor de lixo e, por fim, o desempenho do aplicativo.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. Por outro lado, nenhuma Boxing ocorre conforme os tipos de referência são convertidos.In contrast, no such boxing occurs as reference types are cast. (Para obter mais informações, consulte boxing e unboxing).(For more information, see Boxing and Unboxing).

Em seguida, atribuições de tipo de referência copiam a referência, enquanto atribuições de tipo de valor copiam o valor inteiro.Next, reference type assignments copy the reference, whereas value type assignments copy the entire value. Portanto, as atribuições de tipos de referência grandes são mais baratas do que as atribuições de tipos de valor grande.Therefore, assignments of large reference types are cheaper than assignments of large value types.

Por fim, os tipos de referência são passados por referência, enquanto os tipos de valor são passados por valor.Finally, reference types are passed by reference, whereas value types are passed by value. As alterações em uma instância de um tipo de referência afetam todas as referências que apontam para a instância.Changes to an instance of a reference type affect all references pointing to the instance. As instâncias de tipo de valor são copiadas quando são passadas por valor.Value type instances are copied when they are passed by value. Quando uma instância de um tipo de valor é alterada, é claro que não afeta nenhuma de suas cópias.When an instance of a value type is changed, it of course does not affect any of its copies. Como as cópias não são criadas explicitamente pelo usuário, mas são criadas implicitamente quando argumentos são passados ou valores de retorno são retornados, os tipos de valor que podem ser alterados podem ser confusos para muitos usuários.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. Portanto, os tipos de valor devem ser imutáveis.Therefore, value types should be immutable.

Como regra geral, a maioria dos tipos em uma estrutura deve ser classes.As a rule of thumb, the majority of types in a framework should be classes. No entanto, há algumas situações em que as características de um tipo de valor tornam mais apropriado o uso de structs.There are, however, some situations in which the characteristics of a value type make it more appropriate to use structs.

✔️ CONSIDERAR a definição de uma struct em vez de uma classe se as instâncias do tipo forem pequenas e geralmente de curta duração ou se forem normalmente inseridas em outros objetos.✔️ 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.

❌ evitar definir uma struct, a menos que o tipo tenha todas as seguintes características:❌ AVOID defining a struct unless the type has all of the following characteristics:

  • Ele representa logicamente um único valor, semelhante a tipos primitivos (int, double, etc.).It logically represents a single value, similar to primitive types (int, double, etc.).

  • Ele tem um tamanho de instância inferior a 16 bytes.It has an instance size under 16 bytes.

  • É imutável.It is immutable.

  • Ele não precisará ser emoldurado com frequência.It will not have to be boxed frequently.

Em todos os outros casos, você deve definir seus tipos como classes.In all other cases, you should define your types as classes.

Partes © 2005, 2009 Microsoft Corporation. Todos os direitos reservados.Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

Reimpresso com permissão da Pearson Education, Inc. das Diretrizes de Design do Framework: convenções, linguagens e padrões para bibliotecas do .NET reutilizável, 2ª edição por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da série de desenvolvimento do Microsoft Windows.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.

Consulte tambémSee also