Compartilhar via


Design da estrutura

Estruturas são tipos de valor. Eles são alocados na pilha ou in-line e são desalocados quando eles estiverem fora do escopo. Em geral, sistema autônomo tipos de valor são mais baratos alocar e desalocar; no entanto, se eles são usados em cenários que exigem uma quantidade significativa de conversão boxing e conversão conversão unboxing, eles executar mal em relação aos tipos de referência. Para obter mais informações, consulte Boxing e unboxing (C# Guia de programação).

Para obter informações adicionais sobre os tipos de referência e tipos de valor, consulte o Visão Geral do CTS (Common Type System).

Não fornecem um construtor padrão para uma estrutura.

Se uma estrutura define um construtor padrão, quando os arrays da estrutura são criados, o common linguagem tempo de execução executa automaticamente o construtor padrão em cada elemento da matriz.

Alguns compiladores, sistema autônomo o compilador translation from VPE for Csharp, não permitir que estruturas ter construtores padrão.

Implemente sistema.IEquatable`1 em tipos de valor.

IEquatable<T> é preferível sobre Equals para determinar se os dois tipos de valores são iguais. Usando a interface, o chamador evita o impacto do desempenho negativo de reflexão de conversão boxing e gerenciado.

Certifique-se de que um estado em que todos sistema autônomo dados de instância está definida sistema autônomo zero, FALSO ou nulo (conforme apropriado) é válido.

Seguindo essa diretriz, suas instâncias de tipo de valor recém-criada não são deixadas no estado inutilizável. Por exemplo, a seguinte estrutura foi desenvolvida incorretamente. O construtor parametrizado serve para garantir um estado válido, mas o construtor não é executado quando uma matriz da estrutura é criada. Isso significa que o campo de instância label é inicializado para null (Nothing no Visual Basic), que inválido para implementação dessa estrutura do ToString.

Public Structure BadStructure

    Private label As String

    Private width As Integer

    Private length As Integer

    Public Sub New(ByVal labelValue As String, ByVal widthValue As Integer, ByVal lengthValue As Integer)
        If ((labelValue = Nothing) _
                    OrElse (labelValue.Length = 0)) Then
            Throw New ArgumentNullException("label")
        End If
        label = labelValue
        width = widthValue
        length = lengthValue
    End Sub

    Public Overrides Function ToString() As String
        ' Accessing label.Length throws a NullReferenceException
        ' when label is null.
        Return String.Format("Label length: {0} Label: {1} Width: {2} Length: {3}", label.Length, label, width, length)
    End Function
End Structure
public  struct BadStructure 
{
    string label;
    int width;
    int length;

    public BadStructure (string labelValue, int widthValue, int lengthValue) 
    {
        if (labelValue == null || labelValue.Length ==0) 
        {
            throw new ArgumentNullException("label");
        }
        label = labelValue;
        width = widthValue;
        length = lengthValue;
    }

    public override string ToString() 
    {
        // Accessing label.Length throws a NullReferenceException
        // when label is null.
        return String.Format("Label length: {0} Label: {1} Width: {2} Length: {3}",
            label.Length, label, width,length);
    }
}

No exemplo de código a seguir, o design de GoodStructure não faz nenhuma suposições sobre o estado das label campo. The ToString método foi projetado para lidar com um null rótulo.

Public Structure GoodStructure

    Private label As String

    Private width As Integer

    Private length As Integer

    Public Sub New(ByVal labelValue As String, ByVal widthValue As Integer, ByVal lengthValue As Integer)
        label = labelValue
        width = widthValue
        length = lengthValue
    End Sub

    Public Overrides Function ToString() As String
        ' Handle the case where label might be 
        ' initialized to null;
        Dim formattedLabel As String = label
        Dim formattedLableLength As Integer
        If (formattedLabel = Nothing) Then
            formattedLabel = "<no label value specified>"
            formattedLableLength = 0
        Else
            formattedLableLength = label.Length
        End If
        Return String.Format("Label Length: {0} Label: {1} Width: {2} Length: {3}", formattedLableLength, formattedLabel, width, length)
    End Function
End Structure

public  struct GoodStructure 
{
    string label;
    int width;
    int length;

    public GoodStructure (string labelValue, int widthValue, int lengthValue) 
    {
        label = labelValue;
        width = widthValue;
        length = lengthValue;
    }

    public override string ToString() 
    {
        // Handle the case where label might be 
        // initialized to null;
        string formattedLabel = label;
        int formattedLableLength;
        if (formattedLabel == null)
        {
            formattedLabel = "<no label value specified>";
            formattedLableLength = 0;
        } else
        {
            formattedLableLength = label.Length;
        }
        return String.Format("Label Length: {0} Label: {1} Width: {2} Length: {3}",
            formattedLableLength, formattedLabel, width, length);
    }
}

Não se explicitamente estendem sistema.ValueType.

Alguns compiladores não permitem que você estender ValueType.

Partes direitos autorais 2005 Microsoft Corporation. Todos os direitos reservados.

Partes direitos autorais Addison-Wesley Corporation. Todos os direitos reservados.

Para obter mais informações sobre diretrizes de design, consulte a "diretrizes de design do estrutura: Catálogo de convenções, idiomas e padrões para bibliotecas do .NET reutilizável"Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.

Consulte também

Conceitos

Escolhendo entre estruturas e classes

Outros recursos

Diretrizes de design de tipo

Diretrizes de Design para desenvolvimento bibliotecas de classe