3. struct 값 의미론, 박싱, 가변 구조체의 함정
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// ============================================================================
// [언어 내부동작 문제] C# - struct 값 의미론, 박싱, 가변 구조체의 함정
// ----------------------------------------------------------------------------
// 주제:
// 값 타입(struct)의 복사 의미론(대입/전달 시 복사), 컬렉션에서 "원소가 변수인가
// 복사본인가"의 차이(배열 vs List 인덱서), 박싱이 만드는 복사본, 그리고 가변(mutable)
// 구조체가 일으키는 직관에 어긋나는 동작.
//
// 과제:
// 1) 아래 Main 의 각 WriteLine 이 무엇을 출력하는지 정확히 예측하라.
// 2) arr[0] 변경은 반영되는데 list[0] 변경은 왜 반영되지 않는지(인덱서 반환값) 설명하라.
// 3) boxed 의 X 가 c 와 왜 달라지는지(박싱 시점의 복사) 설명하라.
// 4) 왜 "가변 구조체"가 일반적으로 안티패턴으로 권장되지 않는지 정리하라.
// (먼저 직접 예측·설명을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
using System;
using System.Collections.Generic;
public struct Point
{
public int X;
public void IncX() { X++; }
}
public class Holder
{
public Point P;
}
public class Program
{
public static void Main()
{
// 1) 값 복사
Point a = new Point { X = 1 };
Point b = a;
b.IncX();
Console.WriteLine($"a.X={a.X}, b.X={b.X}");
// 2) 배열 vs List 의 원소 변경
Point[] arr = { new Point { X = 10 } };
arr[0].IncX();
Console.WriteLine($"arr[0].X={arr[0].X}");
List<Point> list = new List<Point> { new Point { X = 20 } };
var tmp = list[0];
tmp.IncX();
Console.WriteLine($"list[0].X={list[0].X}");
// 3) 박싱과 인터페이스/object 를 통한 접근
Point c = new Point { X = 100 };
object boxed = c; // 박싱
c.IncX();
Console.WriteLine($"c.X={c.X}, boxed.X={((Point)boxed).X}");
// 4) class 필드인 struct 직접 변경
Holder h = new Holder();
h.P.X = 5;
h.P.IncX();
Console.WriteLine($"h.P.X={h.P.X}");
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.