Share via


结构设计

结构是值类型。 结构是在堆栈上或以内联方式分配的,当结构超出范围时将被释放。 通常情况下,值类型的内存空间分配和释放的开销较小;但在需要大量装箱和取消装箱操作的方案中,值类型的执行性能较引用类型要差。 有关更多信息,请参见装箱和取消装箱(C# 编程指南)

有关值类型和引用类型的更多信息,请参见 常规类型系统

不要为结构提供默认的构造函数。

如果某一结构定义了默认构造函数,则在创建该结构的数组时,公共语言运行时会自动对每个数组元素执行该默认构造函数。

有些编译器(如 C# 编译器)不允许结构拥有默认构造函数。

对值类型实现 System.IEquatable`1。

在确定两个值类型是否相等时,IEquatable<T> 要优于 Equals。 通过使用接口,调用方可避免装箱和托管反射的不良性能影响。

确保所有实例数据均设置为零、false 或 null(根据需要)的状态是无效的。

如果遵循这一准则,新构造的值类型实例不会处于不可用的状态。 例如,下面的结构的设计是错误的。 参数化构造函数有意确保存在有效的状态,但在创建结构数组时不执行该构造函数。 这意味着实例字段 label 初始化为 null(在 Visual Basic 中为 Nothing),这对于此结构的 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);
    }
}

在下面的代码示例中,GoodStructure 的设计对 label 字段的状态未作任何假定。 ToString 方法设计为处理 null 标签。

    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);
    }
}

不要显式扩展 System.ValueType。

有些编译器不允许扩展 ValueType

部分版权所有 2005 Microsoft Corporation。 保留所有权利。

部分版权所有 Addison-Wesley Corporation。 保留所有权利。

设计指引的详细信息,请参阅"框架设计准则: 公约、 成语和可重复使用的模式。网络图书馆"书 Krzysztof Cwalina 和布拉德 · 艾布拉姆斯,2005年艾迪生 - 韦斯利,发表。

请参见

概念

在类和结构之间选择

其他资源

类型设计准则

类库开发的设计准则