다음을 통해 공유


값 형식(C# 참조)

값 형식참조 형식은 C# 형식의 두 가지 주요 범주입니다. 값 형식의 변수에는 형식의 인스턴스가 포함되어 있습니다. 이는 형식 인스턴스에 대한 참조를 포함하는 참조 형식의 변수와 다릅니다. 기본적으로 변수 값은 할당 시에, 인수를 메서드에 전달할 때, 그리고 메서드 결과를 반환할 때 복사됩니다. 값 형식 변수의 경우 해당 형식 인스턴스가 복사됩니다. 다음 예제에서는 해당 동작을 보여줍니다.

using System;

public struct MutablePoint
{
    public int X;
    public int Y;

    public MutablePoint(int x, int y) => (X, Y) = (x, y);

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

public class Program
{
    public static void Main()
    {
        var p1 = new MutablePoint(1, 2);
        var p2 = p1;
        p2.Y = 200;
        Console.WriteLine($"{nameof(p1)} after {nameof(p2)} is modified: {p1}");
        Console.WriteLine($"{nameof(p2)}: {p2}");

        MutateAndDisplay(p2);
        Console.WriteLine($"{nameof(p2)} after passing to a method: {p2}");
    }

    private static void MutateAndDisplay(MutablePoint p)
    {
        p.X = 100;
        Console.WriteLine($"Point mutated in a method: {p}");
    }
}
// Expected output:
// p1 after p2 is modified: (1, 2)
// p2: (1, 200)
// Point mutated in a method: (100, 200)
// p2 after passing to a method: (1, 200)

앞의 예제와 같이 값 형식 변수에 대한 작업은 변수에 저장된 값 형식의 인스턴스에만 영향을 줍니다.

값 형식이 참조 형식의 데이터 구성원을 포함하는 경우에는 값 형식 인스턴스가 복사될 때 참조 형식의 인스턴스에 대한 참조만 복사됩니다. 복사 및 원래 값 형식 인스턴스는 모두 동일한 참조 형식 인스턴스에 액세스할 수 있습니다. 다음 예제에서는 해당 동작을 보여줍니다.

using System;
using System.Collections.Generic;

public struct TaggedInteger
{
    public int Number;
    private List<string> tags;

    public TaggedInteger(int n)
    {
        Number = n;
        tags = new List<string>();
    }

    public void AddTag(string tag) => tags.Add(tag);

    public override string ToString() => $"{Number} [{string.Join(", ", tags)}]";
}

public class Program
{
    public static void Main()
    {
        var n1 = new TaggedInteger(0);
        n1.AddTag("A");
        Console.WriteLine(n1);  // output: 0 [A]

        var n2 = n1;
        n2.Number = 7;
        n2.AddTag("B");

        Console.WriteLine(n1);  // output: 0 [A, B]
        Console.WriteLine(n2);  // output: 7 [A, B]
    }
}

참고 항목

코드를 오류가 덜 발생하고 더 강력하게 만들려면 변경할 수 없는 값 형식을 정의 및 사용합니다. 이 문서에서는 데모용으로만 변경 가능한 값 형식을 사용합니다.

값 형식 및 형식 제약 조건의 종류

값 형식은 다음 두 가지 중 하나일 수 있습니다.

  • 데이터 및 관련 기능을 캡슐화하는구조 형식
  • 명명된 상수 집합으로 정의되고 선택 사항 또는 선택 사항의 조합을 나타내는 열거 형식

기본 값 형식 T의 모든 값과 추가 Null 값을 나타내는 값 형식 T? Null 허용 값 형식인 경우를 제외하고는 값 형식의 변수에 null을 할당할 수 없습니다.

struct 제약 조건을 사용하여 형식 매개 변수가 null을 허용하지 않는 값 형식이라고 지정할 수 있습니다. 구조체 형식과 열거형 형식 모두 struct 제약 조건을 충족합니다. 기본 클래스 제약 조건(열거형 제약 조건이라고 함)에서 System.Enum을 사용하여 형식 매개 변수가 열거형 형식이라고 지정할 수 있습니다.

기본 제공 값 형식

C#은 단순 형식이라고도 하는 다음과 같은 기본 제공 값 형식을 제공합니다.

모든 단순 형식은 구조체 형식이며, 특정 추가 작업을 허용한다는 점에서 다른 구조체 형식과 다릅니다.

  • 리터럴을 사용하여 단순 형식의 값을 제공할 수 있습니다.
    예를 들어 형식 'A' 의 리터럴이고 형식 char2001 의 리터럴이며 12.34m 형식 int decimal의 리터럴입니다.

  • const 키워드를 사용하여 단순 형식의 상수를 선언할 수 있습니다.
    예를 들어 .const decimal = 12.34m
    다른 구조체 형식의 상수는 포함할 수 없습니다.

  • 해당 피연산자가 모두 단순 형식의 상수인 상수 식은 컴파일 시간에 계산됩니다.

값 튜플은 단순 형식이 아닌 값 형식입니다.

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.

참고 항목