16. readonly struct · in 매개변수 · 방어적 복사(defensive copy)
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 주제: readonly struct · in 매개변수 · 방어적 복사(defensive copy).
//
// 가변(비 readonly) 구조체의 "비 readonly 메서드"를 readonly 컨텍스트(readonly 필드,
// in 매개변수, ref readonly)에서 호출하면, 컴파일러는 그 메서드가 상태를 바꿀 수도
// 있다고 보고 호출 전에 구조체를 "방어적으로 복사"한 뒤 복사본에서 메서드를 실행한다.
//
// 과제:
// 1) 이 프로그램의 정확한 표준출력을 예측하라(세 줄 모두).
// 2) (1)(2) 의 결과가 (3) 의 직접 호출과 왜 다른지 — 방어적 복사가 언제, 왜 끼어드는지
// 내부 동작으로 설명하라.
// 3) 이 방어적 복사가 정확성(변경이 사라짐)과 성능(숨은 복사 비용) 양쪽에
// 어떤 문제를 일으키는지, 그리고 어떻게 제거하는지 설명하라.
using System;
struct Counter // 가변 구조체(비 readonly)
{
public int Value;
public int Next() // 비 readonly 메서드: 상태를 바꾼다
{
Value++;
return Value;
}
}
class Program
{
static readonly Counter s_counter = new Counter { Value = 10 };
static int CallNext(in Counter c) => c.Next(); // in: 읽기 전용 참조
static void Main()
{
// (1) readonly 필드를 통해 비readonly 메서드 호출
int a = s_counter.Next();
int b = s_counter.Next();
Console.WriteLine($"a={a} b={b} field={s_counter.Value}");
// (2) in 매개변수를 통해 비readonly 메서드 호출
Counter local = new Counter { Value = 100 };
int n1 = CallNext(in local);
int n2 = CallNext(in local);
Console.WriteLine($"n1={n1} n2={n2} local={local.Value}");
// (3) 평범한 지역 변수에서 직접 호출(복사 없음)
Counter direct = new Counter { Value = 0 };
int d1 = direct.Next();
int d2 = direct.Next();
Console.WriteLine($"d1={d1} d2={d2} direct={direct.Value}");
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.