값 형식 및 참조 형식은 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]
}
}
값 형식 및 형식 제약 조건의 종류
값 형식은 다음 두 가지 중 하나일 수 있습니다.
1. 데이터 및 관련 기능을 캡슐화하는 구조 형식.
2. 명명된 상수 집합으로 정의되고 선택 사항 또는 선택 사항의 조합을 나타내는 열거 형식.
nullable 값 형식은 기본 값 형식 T? T 의 모든 값과 추가 null 값을 나타냅니다.
Null 값 형식인 경우를 제외하고는 값 형식의 변수에 null을 할당할 수 없습니다.
struct 제약 조건을 사용하여 형식 매개 변수가 null을 허용하지 않는 값 형식이라고 지정할 수 있습니다.
구조체 형식과 열거형 형식 모두 struct 제약 조건을 충족합니다.
키본 클래스 제약 조건에서 형식 매개 변수가 열거형 형식임을 지정하는 데 System.Enum을 사용할 수 있습니다.
기본 제공 값 형식
C#은 단순 형식이라고도 하는 다음과 같은 기본 제공 값 형식을 제공합니다.
- 정수 숫자 형식
- 부동 소수점 숫자 형식
- 부울 값을 나타내는 bool
- 유니코드 UTF-16 문자를 나타내는 문자
모든 단순 형식은 구조체 형식이며, 특정 추가 작업을 허용한다는 점에서 다른 구조체 형식과 다릅니다.
- 리터럴을 사용하여 단순 형식의 값을 제공할 수 있습니다. 예를들어 'A'는 char형식의 리터럴이고, 2001은 int 형식의 리터럴입니다.
- const 키워드를 사용하여 단순 형식의 상수를 선언할 수 있습니다. 다른 구조체 형식의 상수는 포함할 수 없습니다.
- 해당 피연산자가 모두 단순 형식의 상수인 상수 식은 컴파일 시간에 계산됩니다.
값 튜플은 값 형식이지만 단순 형식은 아닙니다.
C#에서는 단순 형식이라는 미리 정의된 구조체 형식의 집합을 제공합니다.
단순 형식은 예약어를 통해 식별됩니다.
value_type
: struct_type
| enum_type
;
struct_type
: type_name
| simple_type
| nullable_type
;
simple_type
: numeric_type
| 'bool'
;
numeric_type
: integral_type
| floating_point_type
| 'decimal'
;
integral_type
: 'sbyte'
| 'byte'
| 'short'
| 'ushort'
| 'int'
| 'uint'
| 'long'
| 'ulong'
| 'char'
;
floating_point_type
: 'float'
| 'double'
;
nullable_type
: non_nullable_value_type '?'
;
non_nullable_value_type
: type
;
enum_type
: type_name
;
참조 형식은 변수와 달리 null 값 형식의 변수는 값 형식이 nullable 형식인 경우에만 값을 포함할 수 있습니다.
Null을 허용 하지 않는 모든 값 형식에 대해 null 값과 값의 동일한 집합을 나타내는 해당 nullable 값 형식이 있습니다.
값 형식의 변수에 할당 하면 할당 되는 값의 복사본이 생성됩니다.
이는 참조를 복사하지만 참조로 식별되는 개체가 아닌 참조 형식의 변수에 대한 할당과 다릅니다.
'C#' 카테고리의 다른 글
C# Value Type : 값 형식 - 부동 소수점 숫자 형식 (2) | 2023.01.16 |
---|---|
C# Value Type : 값 형식 - 정수 숫자 형식 (0) | 2023.01.12 |
C# Boxing 및 Unboxing : 박싱 및 언박싱 (0) | 2023.01.11 |
C# Type Conversion : 형변환 (0) | 2023.01.10 |
C# Memory : 메모리 (0) | 2023.01.10 |