구조체 디자인

구조체는 값 형식으로, 스택에 할당되거나 인라인으로 할당되고 범위를 벗어나면 할당이 취소됩니다. 일반적으로 값 형식은 할당 및 할당 취소하기 쉽지만, 많은 양의 boxing과 unboxing이 필요한 시나리오에서 사용하는 경우 참조 형식과 비교해 볼 때 성능이 떨어집니다. 자세한 내용은 Boxing 및 Unboxing(C# 프로그래밍 가이드)을 참조하십시오.

값 형식 및 참조 형식에 대한 자세한 내용은 공용 형식 시스템을 참조하십시오.

구조체에 기본 생성자를 제공하지 않습니다.

구조체의 배열을 만들 때 구조체에서 기본 생성자를 정의하는 경우 공용 언어 런타임은 각 배열 요소에서 자동으로 기본 생성자를 실행합니다.

C# 컴파일러와 같은 일부 컴파일러에서는 구조체에 기본 생성자가 있으면 안 됩니다.

값 형식에서 System.IEquatable`1을 구현합니다.

두 값 형식이 같은지 여부를 확인할 때 Equals보다 IEquatable<T>이 더 많이 사용됩니다. 인터페이스를 사용하면 호출자는 boxing 및 관리되는 리플렉션의 성능에 부정적인 영향을 주는 것을 방지할 수 있습니다.

모든 인스턴스 데이터가 0, false 또는 null로 적절히 설정되어 있는 상태가 올바른지 확인합니다.

이 지침을 따르면 새로 생성된 값 형식 인스턴스가 사용할 수 없는 상태가 되지 않습니다. 예를 들어, 다음은 잘못 디자인된 구조체입니다. 매개 변수화된 생성자는 유효한 상태를 보장하지만 구조체의 배열을 만들 때는 실행되지 않습니다. 즉, 인스턴스 필드 label은 이 구조체의 ToString 구현용으로 사용할 수 없는 null(Visual Basic의 경우 Nothing)로 초기화됩니다.

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을 확장할 수 없습니다.

Portions Copyright 2005 Microsoft Corporation. 모든 권리 보유.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

디자인 지침에 자세한 내용은 참조를 "Framework 디자인 지침: 규칙, 숙어, 및 재사용에 대 한 패턴입니다.NET 라이브러리"도 서 Krzysztof Cwalina와 Brad Abrams, 게시 Addison-wesley, 2005.

참고 항목

개념

클래스와 구조체 간의 선택

기타 리소스

형식 디자인 지침

클래스 라이브러리 개발을 위한 디자인 지침