30. 정적 생성자와 타입 초기화 타이밍(beforefieldinit)
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 주제: 정적 생성자(static constructor)와 타입 초기화 타이밍, beforefieldinit
//
// 과제:
// 1) 아래 프로그램의 출력을 순서까지 예측하라.
// 2) 명시적 정적 생성자가 있는 타입과 없는 타입(필드 이니셜라이저만)의 초기화 시점이
// 어떻게 다른지(beforefieldinit 플래그), "정확히 언제" 타입 초기화가 트리거되는지 설명하라.
// 3) 마지막 두 줄(Mutual.A / Mutual.B)에서 순환 정적 초기화가 어떤 값을 관측하게 되는지 설명하라.
// (내부 동작 설명은 answer.md 에)
using System;
public static class Program
{
public static void Main()
{
Console.WriteLine("start");
Console.WriteLine(Config.Value); // beforefieldinit 후보 타입
Console.WriteLine(Counter.Next()); // 명시적 static ctor 보유
Console.WriteLine(Counter.Next());
Console.WriteLine("--- mutual ---");
Console.WriteLine(Mutual.A); // 먼저 접근되는 쪽
Console.WriteLine(Mutual.B);
}
}
public static class Config
{
public static readonly int Value = Load();
private static int Load() { Console.WriteLine("Config.Load"); return 42; }
}
public static class Counter
{
private static int _n;
static Counter() { Console.WriteLine("Counter..cctor"); _n = 100; }
public static int Next() => ++_n;
}
// 순환 정적 초기화: A 초기화가 B 를, B 초기화가 A 를 참조한다.
public static class Mutual
{
public static readonly int A = ComputeA();
public static readonly int B = 10;
private static int ComputeA() => Mutual2.Bv + 1;
}
public static class Mutual2
{
public static readonly int Bv = ComputeB();
public static readonly int Av = 5;
private static int ComputeB() => Mutual.B + 1; // 이 시점 Mutual.B 값에 주의
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.