Tipos de estrutura (referência C#)Structure types (C# reference)

Um tipo de estrutura (ou tipo de estrutura) é um tipo de valor que pode encapsular dados e funcionalidades relacionadas.A structure type (or struct type) is a value type that can encapsulate data and related functionality. Você usa struct a palavra-chave para definir um tipo de estrutura:You use the struct keyword to define a structure type:

public struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; }
    public double Y { get; }

    public override string ToString() => $"({X}, {Y})";
}

Os tipos de estrutura têm semântica de valor.Structure types have value semantics. Ou seja, uma variável de um tipo de estrutura contém uma instância do tipo.That is, a variable of a structure type contains an instance of the type. Por padrão, os valores variáveis são copiados na atribuição, passando um argumento para um método e retornando um resultado do método.By default, variable values are copied on assignment, passing an argument to a method, and returning a method result. No caso de uma variável do tipo estrutura, uma instância do tipo é copiada.In the case of a structure-type variable, an instance of the type is copied. Para obter mais informações, consulte Tipos de valor.For more information, see Value types.

Normalmente, você usa tipos de estrutura para projetar pequenos tipos centrados em dados que fornecem pouco ou nenhum comportamento.Typically, you use structure types to design small data-centric types that provide little or no behavior. Por exemplo, .NET usa tipos de estrutura para representar um número (inteiro e real),um valor booleano,um caractere Unicode,uma instância de tempo.For example, .NET uses structure types to represent a number (both integer and real), a Boolean value, a Unicode character, a time instance. Se você está focado no comportamento de um tipo, considere definir uma classe.If you're focused on the behavior of a type, consider defining a class. Os tipos de classe têm semântica de referência.Class types have reference semantics. Ou seja, uma variável de um tipo de classe contém uma referência a uma instância do tipo, não à instância em si.That is, a variable of a class type contains a reference to an instance of the type, not the instance itself.

Como os tipos de estrutura têm semântica de valor, recomendamos que você defina tipos de estrutura imutáveis.Because structure types have value semantics, we recommend you to define immutable structure types.

readonlyStructreadonly struct

Começando com C# 7.2, readonly você usa o modificador para declarar que um tipo de estrutura é imutável:Beginning with C# 7.2, you use the readonly modifier to declare that a structure type is immutable:

public readonly struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; }
    public double Y { get; }

    public override string ToString() => $"({X}, {Y})";
}

Todos os membros readonly de dados de uma estrutura devem ser lidos apenas da seguinte forma:All data members of a readonly struct must be read-only as follows:

  • Qualquer declaração de campo deve ter o readonly modificadorAny field declaration must have the readonly modifier
  • Qualquer propriedade, incluindo as implementadas automaticamente, deve ser somente leituraAny property, including auto-implemented ones, must be read-only

Isso garante que nenhum readonly membro de uma estrutura modifica o estado da estrutura.That guarantees that no member of a readonly struct modifies the state of the struct.

Observação

Em readonly uma estrutura, um membro de dados de um tipo de referência mutável ainda pode mutar seu próprio estado.In a readonly struct, a data member of a mutable reference type still can mutate its own state. Por exemplo, você não List<T> pode substituir uma instância, mas você pode adicionar novos elementos a ele.For example, you can't replace a List<T> instance, but you can add new elements to it.

readonlymembros de instânciareadonly instance members

Começando com C# 8.0, você readonly também pode usar o modificador para declarar que um membro de instância não modifica o estado de uma estrutura.Beginning with C# 8.0, you can also use the readonly modifier to declare that an instance member doesn't modify the state of a struct. Se você não puder declarar todo readonlyo readonly tipo de estrutura como , use o modificador para marcar os membros de instância que não modificam o estado da estrutura.If you can't declare the whole structure type as readonly, use the readonly modifier to mark the instance members that don't modify the state of the struct. Em readonly uma estrutura, cada membro de readonlyinstância é implicitamente .In a readonly struct, every instance member is implicitly readonly.

Dentro readonly de um membro de instância, você não pode atribuir aos campos de instância da estrutura.Within a readonly instance member, you can't assign to structure's instance fields. No entanto, um readonly membroreadonly pode chamar um não-membro.However, a readonly member can call a non-readonly member. Nesse caso, o compilador cria uma cópia da instânciareadonly da estrutura e chama o não-membro nessa cópia.In that case the compiler creates a copy of the structure instance and calls the non-readonly member on that copy. Como resultado, a instância original da estrutura não é modificada.As a result, the original structure instance is not modified.

Normalmente, você readonly aplica o modificador aos seguintes tipos de membros de instância:Typically, you apply the readonly modifier to the following kinds of instance members:

  • Métodos:methods:

    public readonly double Sum()
    {
        return X + Y;
    }
    

    Você também pode readonly aplicar o modificador a métodos System.Objectque anulam métodos declarados em :You can also apply the readonly modifier to methods that override methods declared in System.Object:

    public readonly override string ToString() => $"({X}, {Y})";
    
  • propriedades e indexadores:properties and indexers:

    private int counter;
    public int Counter
    {
        readonly get => counter;
        set => counter = value;
    }
    

    Se você precisar readonly aplicar o modificador em ambos os acessórios de uma propriedade ou indexador, aplique-o na declaração do imóvel ou indexador.If you need to apply the readonly modifier to both accessors of a property or indexer, apply it in the declaration of the property or indexer.

    Observação

    O compilador declara get um acessório de uma readonly propriedade auto-implementada readonly como , independentemente da presença do modificador em uma declaração de propriedade.The compiler declares a get accessor of an auto-implemented property as readonly, regardless of presence of the readonly modifier in a property declaration.

Você não pode readonly aplicar o modificador a membros estáticos de um tipo de estrutura.You can't apply the readonly modifier to static members of a structure type.

O compilador pode fazer readonly uso do modificador para otimizações de desempenho.The compiler may make use of the readonly modifier for performance optimizations. Para obter mais informações, consulte Escrever código C# seguro e eficiente.For more information, see Write safe and efficient C# code.

Limitações com o design de um tipo de estruturaLimitations with the design of a structure type

Quando você projeta um tipo de estrutura, você tem os mesmos recursos que com um tipo de classe, com as seguintes exceções:When you design a structure type, you have the same capabilities as with a class type, with the following exceptions:

  • Você não pode declarar um construtor sem parâmetros.You can't declare a parameterless constructor. Cada tipo de estrutura já fornece um construtor implícito sem parâmetros que produz o valor padrão do tipo.Every structure type already provides an implicit parameterless constructor that produces the default value of the type.

  • Você não pode inicializar um campo de instância ou propriedade em sua declaração.You can't initialize an instance field or property at its declaration. No entanto, você pode inicializar um campo estático ou const ou uma propriedade estática em sua declaração.However, you can initialize a static or const field or a static property at its declaration.

  • Um construtor de um tipo de estrutura deve inicializar todos os campos de instância do tipo.A constructor of a structure type must initialize all instance fields of the type.

  • Um tipo de estrutura não pode herdar de outra classe ou tipo de estrutura e não pode ser a base de uma classe.A structure type can't inherit from other class or structure type and it can't be the base of a class. No entanto, um tipo de estrutura pode implementar interfaces.However, a structure type can implement interfaces.

  • Você não pode declarar um finalizador dentro de um tipo de estrutura.You can't declare a finalizer within a structure type.

Instantiva de um tipo de estruturaInstantiation of a structure type

Em C#, você deve inicializar uma variável declarada antes que ela possa ser usada.In C#, you must initialize a declared variable before it can be used. Como uma variável de tipo null de estrutura não pode ser (a menos que seja uma variável de um tipo de valor anulado),você deve instanciar uma instância do tipo correspondente.Because a structure-type variable can't be null (unless it's a variable of a nullable value type), you must instantiate an instance of the corresponding type. Há várias maneiras de fazer isso.There are several ways to do that.

Normalmente, você instancia um tipo de estrutura new ligando para um construtor apropriado com o operador.Typically, you instantiate a structure type by calling an appropriate constructor with the new operator. Cada tipo de estrutura tem pelo menos um construtor.Every structure type has at least one constructor. É um construtor implícito sem parâmetros, que produz o valor padrão do tipo.That's an implicit parameterless constructor, which produces the default value of the type. Você também pode usar uma expressão de valor padrão para produzir o valor padrão de um tipo.You can also use a default value expression to produce the default value of a type.

Se todos os campos de exemplo de um tipo de new estrutura estiverem acessíveis, você também poderá instancia-lo sem o operador.If all instance fields of a structure type are accessible, you can also instantiate it without the new operator. Nesse caso, você deve inicializar todos os campos de instância antes do primeiro uso da instância.In that case you must initialize all instance fields before the first use of the instance. O seguinte exemplo mostra como fazer isso:The following example shows how to do that:

public static class StructWithoutNew
{
    public struct Coords
    {
        public double x;
        public double y;
    }

    public static void Main()
    {
        Coords p;
        p.x = 3;
        p.y = 4;
        Console.WriteLine($"({p.x}, {p.y})");  // output: (3, 4)
    }
}

No caso dos tipos de valor embutidos,use os literais correspondentes para especificar um valor do tipo.In the case of the built-in value types, use the corresponding literals to specify a value of the type.

Passando variáveis de tipo de estrutura por referênciaPassing structure-type variables by reference

Quando você passa uma variável de tipo de estrutura para um método como argumento ou retorna um valor de tipo de estrutura a partir de um método, toda a instância de um tipo de estrutura é copiada.When you pass a structure-type variable to a method as an argument or return a structure-type value from a method, the whole instance of a structure type is copied. Isso pode afetar o desempenho do seu código em cenários de alto desempenho que envolvem grandes tipos de estrutura.That can affect the performance of your code in high-performance scenarios that involve large structure types. Você pode evitar a cópia de valor passando uma variável tipo de estrutura por referência.You can avoid value copying by passing a structure-type variable by reference. Use refos outmodificadores do parâmetro , ou in método para indicar que um argumento deve ser aprovado por referência.Use the ref, out, or in method parameter modifiers to indicate that an argument must be passed by reference. Use o retorno do ref para retornar um resultado do método por referência.Use ref returns to return a method result by reference. Para obter mais informações, consulte Escrever código C# seguro e eficiente.For more information, see Write safe and efficient C# code.

refStructref struct

Começando com C# 7.2, ref você pode usar o modificador na declaração de um tipo de estrutura.Beginning with C# 7.2, you can use the ref modifier in the declaration of a structure type. As instâncias de um ref tipo de estrutura são alocadas na pilha e não podem escapar para o monte gerenciado.Instances of a ref struct type are allocated on the stack and can't escape to the managed heap. Para garantir isso, o compilador ref limita o uso de tipos de estruturada da seguinte forma:To ensure that, the compiler limits the usage of ref struct types as follows:

  • Uma ref estrutura não pode ser o tipo de elemento de uma matriz.A ref struct can't be the element type of an array.
  • Uma ref estrutura não pode ser um tipo declarado de um camporef de uma classe ou uma não-estrutura.A ref struct can't be a declared type of a field of a class or a non-ref struct.
  • Uma ref estrutura não pode implementar interfaces.A ref struct can't implement interfaces.
  • Uma ref estrutura não pode ser encaixotada System.ValueType ou. System.ObjectA ref struct can't be boxed to System.ValueType or System.Object.
  • Uma ref estrutura não pode ser um tipo de argumento.A ref struct can't be a type argument.
  • Uma ref variável de estruturanão pode ser capturada por uma expressão lambda ou uma função local.A ref struct variable can't be captured by a lambda expression or a local function.
  • Uma ref variável de estruturanão pode ser async usada em um método.A ref struct variable can't be used in an async method. No entanto, ref você pode usar variáveis de estrutura em métodos síncronos, por exemplo, naqueles que retornam Task ou Task<TResult>.However, you can use ref struct variables in synchronous methods, for example, in those that return Task or Task<TResult>.
  • Uma ref variável de estruturanão pode ser usada em iteradores.A ref struct variable can't be used in iterators.

Normalmente, você ref define um tipo de estruturação quando precisa de ref um tipo que também inclua membros de dados de tipos de estrutura:Typically, you define a ref struct type when you need a type that also includes data members of ref struct types:

public ref struct CustomRef
{
    public bool IsValid;
    public Span<int> Inputs;
    public Span<int> Outputs;
}

Para declarar ref uma estrutura readonlycomo readonly , ref combine os modificadores e readonly modificadores na ref declaração do tipo (o modificador deve vir antes do modificador):To declare a ref struct as readonly, combine the readonly and ref modifiers in the type declaration (the readonly modifier must come before the ref modifier):

public readonly ref struct ConversionRequest
{
    public ConversionRequest(double rate, ReadOnlySpan<double> values)
    {
        Rate = rate;
        Values = values;
    }

    public double Rate { get; }
    public ReadOnlySpan<double> Values { get; }
}

Em .NET, exemplos ref de uma System.Span<T> estrutura System.ReadOnlySpan<T>são e .In .NET, examples of a ref struct are System.Span<T> and System.ReadOnlySpan<T>.

ConversõesConversions

Para qualquer tipo de estrutura (exceto System.ValueType System.Object ref tipos de estrutura), existem conversões de boxe e unboxing para e dos tipos.For any structure type (except ref struct types), there exist boxing and unboxing conversions to and from the System.ValueType and System.Object types. Existem também conversões de boxe e unboxing entre um tipo de estrutura e qualquer interface que implemente.There exist also boxing and unboxing conversions between a structure type and any interface that it implements.

especificação da linguagem C#C# language specification

Para obter mais informações, consulte a seção Structs da especificação do idioma C#.For more information, see the Structs section of the C# language specification.

Para obter mais informações sobre os recursos introduzidos no C# 7.2 e posteriores, consulte as seguintes notas de proposta de recurso:For more information about features introduced in C# 7.2 and later, see the following feature proposal notes:

Confira tambémSee also