CodeGym /행동 /C# SELF /튜플 요소 네이밍과 튜플 디컨스트럭션

튜플 요소 네이밍과 튜플 디컨스트럭션

C# SELF
레벨 11 , 레슨 2
사용 가능

1. 튜플 네이밍: 디컨스트럭션을 위한 컨텍스트

이전 강의에서 이미 튜플에 이름을 붙여서 Item1, Item2 같은 의미 없는 이름 대신, person.Name처럼 의미 있는 이름으로 값에 접근할 수 있다는 걸 배웠지. 튜플 요소에 이름을 붙이는 건, 특히 메서드의 반환값이나 파라미터, 프로퍼티로 쓸 때 코드가 훨씬 읽기 쉬워져서 중요해. 네이밍이 바로 우리가 이 강의에서 배울 디컨스트럭션을 편하게 해주는 핵심 전제야.

참고로, 이름은 튜플 리터럴로 초기화할 때나, 메서드/프로퍼티/필드의 반환 타입 시그니처에서 지정할 수 있어.

메서드 예시: 메서드 반환값에서 네이밍된 튜플 요소


public static (int 나이, string 이름) GetPetInfo()
{
    return (나이: 5, 이름: "Барсик");
}

// 사용 예시:
var info = GetPetInfo();
Console.WriteLine($"{info.이름} — {info.나이} 살");

필드/프로퍼티 예시: 필드/프로퍼티에서 네이밍된 튜플 요소


public (int 너비, int 높이) ImageSize = (1024, 768);

기억해: 이름을 명시적으로 지정하지 않으면, 요소는 여전히 Item1, Item2 등으로 접근해야 해. 이러면 튜플을 계속 쓸 때 코드가 덜 읽기 쉬워지니까, 의미가 명확하지 않으면 항상 이름을 붙여주는 게 좋아.

2. 튜플 디컨스트럭션

디컨스트럭션이 뭐야?

디컨스트럭션은 튜플을 여러 변수로 "분해"해서 각각 편하게 쓰는 거야. 예를 들어, (나이: 5, 이름: "Барсик") 튜플에서 나이이름 두 변수를 바로 뽑아낼 수 있지.

비유: 튜플이 이름표 붙은 박스라면, 디컨스트럭션은 그 박스 안에 든 걸 바로 책상 위에 꺼내놓는 거랑 똑같아.

디컨스트럭션 문법


var pet = (나이: 5, 이름: "Барсик");
var (age, name) = pet;
Console.WriteLine($"{name} — {age} 살");
튜플을 변수로 디컨스트럭션

이제 agename 두 변수가 생겼어. 이 변수들은 튜플에서 값을 받아온 거고, 왼쪽에 쓴 이름(age, name)은 튜플 안 이름이랑 달라도 돼. 그냥 새로운 로컬 변수일 뿐이야.

함수 반환값 디컨스트럭션

함수에서 여러 값을 반환할 때 튜플을 많이 쓰는데, 이럴 때 디컨스트럭션이 특히 편해:


public static (double 최소값, double 최대값) GetMinMax(int[] data)
{
    int 최소값 = data.Min();
    int 최대값 = data.Max();
    return (최소값, 최대값);
}

var numbers = new[] { 1, 2, 3, 4, 5 };
var (minValue, maxValue) = GetMinMax(numbers);
Console.WriteLine($"최소: {minValue}, 최대: {maxValue}");
함수 반환값 디컨스트럭션

디컨스트럭션할 때 변수 이름은 상황에 맞게 네가 원하는 대로 지으면 돼.

var로 디컨스트럭션

var (a, b) = (10, 20); // int a = 10, b = 20

디컨스트럭션과 discard _

가끔 튜플의 모든 요소가 필요하지 않을 때가 있어. 이럴 땐 _ (discard)로 무시할 수 있어. 디스카드(_)는 "여기 값이 있는 건 아는데, 난 변수 안 만들 거야"라는 뜻이야.

즉, 튜플을 디컨스트럭션하면서 필요 없는 자리에 "구멍"을 뚫는 거지. 간단하고 깔끔하게 쓸 수 있어!


var pet = (나이: 5, 이름: "Барсик", 행복함: true);
var (age, _, isHappy) = pet; // age랑 isHappy만, 이름은 무시
discard _로 디컨스트럭션

꿀팁: 디스카드는 네임스페이스에 필요 없는 변수가 생기는 걸 막아줄 때 자주 써!

foreach에서 디컨스트럭션

C#에서는 튜플 배열을 foreach에서 바로 디컨스트럭션하면서 순회할 수 있어:


var pets = new (string 이름, int 나이)[]
{
    ("Барсик", 5),
    ("Муся", 3),
    ("Джонни", 7)
};

foreach (var (name, age) in pets)
{
    Console.WriteLine($"{name} — {age} 살");
}
foreach에서 튜플 디컨스트럭션

3. 요소 이름과 타입 지정이 어떻게 동작하는지

네이밍된 요소의 동작

튜플 요소의 이름은 "문법 설탕"이야. 즉, 사람을 위한 편의 기능이지. 컴파일할 때 이름은 내부적으로 Item1, Item2 등으로 바뀌지만, IDE랑 컴파일러가 이름을 기억해서 네가 쓸 수 있게 해줘.

타입 호환성과 변환에 미치는 영향

요소 개수랑 타입이 같으면, 이름이 달라도 두 튜플은 같은 타입으로 취급돼. 즉, 요소 이름은 타입 정의에 포함되지 않아:


var t1 = (X: 42, Y: 13);
var t2 = (A: 42, B: 13);
t1 = t2; // OK
Console.WriteLine(t1.X); // 42
요소 이름이 달라도 튜플 타입 호환됨

하지만, 코드에서 쓰거나 IntelliSense 힌트에서는 항상 왼쪽(할당받는 쪽) 이름이 보여.

암시적/명시적 네이밍

이미 배웠지만, 다시 말하면 튜플을 일부만 네이밍하거나 아예 이름 없이 만들 수도 있어. 이름이 없으면 그냥 Item1 등으로 접근해야 해.


var point = (X: 10, 20); // X랑 Item2
Console.WriteLine(point.X);     // 10
Console.WriteLine(point.Item2); // 20
부분적으로 네이밍된 튜플

팁: 튜플에 요소가 2개 이상이거나, 값의 의미가 명확하지 않으면 항상 이름을 붙여줘.

4. 네이밍과 디컨스트럭션에서 자주 하는 실수와 특징

실수 1: 다른 튜플 할당 시 이름이 "이동"되는 현상
처음에 이름 붙인 튜플을 만들고, 나중에 이름 없는(혹은 다른 이름의) 튜플을 할당하면, IntelliSense에는 원래 이름이 계속 보여. 예시:


var original = (X: 1, Y: 2);
var alias = original;            // alias.X == 1, alias.Y == 2

original = (10, 20);             // 이름 없는 튜플
Console.WriteLine(alias.X);      // 여전히 동작, alias는 예전 이름을 유지

실수 2: 요소 이름 중복
두 요소에 같은 이름을 붙이면 안 돼 — 컴파일러가 "Duplicate tuple element name" 에러를 뱉어:


var badTuple = (A: 1, A: 2);     // 에러 CS8122: Duplicate tuple element name 'A'

실수 3: 요소 개수 안 맞는 디컨스트럭션
디컨스트럭션할 때 변수 개수랑 튜플 크기가 정확히 맞아야 해. 안 맞으면 에러 나:


var pet = (나이: 5, 이름: "Барсик");
var (age, name, mood) = pet;     // 에러 CS8124: Tuple must contain exactly 3 elements

실수 4: discard _ 잘못 쓰기
_로 요소를 무시할 때, 각각 따로 써야 하고, 여러 개를 한 번에 건너뛰는 건 안 돼. 예를 들어, 두 개를 한 _로 건너뛰려 하면 에러야:


var data = (1, 2, 3);
var (_, x, _) = data;            // OK: 첫 번째, 세 번째 무시
var (_, _) = data;               // 에러 CS8124: Tuple must contain exactly 2 elements

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION