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 para desenvolvimento bibliotecas de classe