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#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.