10. CLR 제네릭의 런타임 구현(값 형식 특수화·코드 공유·박싱 회피)
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 주제: CLR 제네릭의 런타임 구현 — 값 형식 특수화, 코드 공유, 박싱 회피
//
// 과제: 아래 (A)~(E) 각 지점에서 "박싱(boxing)이 일어나는지"를 예측하고,
// 다음을 내부 동작으로 설명하라.
// 1) 왜 List<int> 는 int 를 박싱하지 않는데 ArrayList 는 박싱하는가?
// 2) CLR 은 제네릭을 런타임에 어떻게 구현하는가? "값 형식 인스턴스화는
// 특수화(specialization), 참조 형식 인스턴스화는 코드 공유(sharing)"가
// 무슨 뜻인가?
// 3) EqualityComparer<T>.Default 는 값 형식의 비교에서 어떻게 박싱을 피하는가?
// 반대로 제약 없는 T 에 대해 a.Equals(b) (object.Equals)는 왜 박싱하는가?
using System;
using System.Collections;
using System.Collections.Generic;
public struct Point : IEquatable<Point>
{
public int X, Y;
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is Point p && Equals(p);
public override int GetHashCode() => unchecked(X * 397) ^ Y;
}
public static class Program
{
static bool GenericEquals<T>(T a, T b)
=> EqualityComparer<T>.Default.Equals(a, b); // (A) 값 형식일 때 박싱?
static bool ObjectEquals<T>(T a, T b)
=> a.Equals(b); // (B) object.Equals 경로 박싱?
public static void Main()
{
ArrayList al = new ArrayList();
al.Add(42); // (C) int 추가
List<int> li = new List<int>();
li.Add(42); // (D) int 추가
var p1 = new Point { X = 1, Y = 2 };
var p2 = new Point { X = 1, Y = 2 };
GenericEquals(p1, p2); // (A) 호출
ObjectEquals(p1, p2); // (B) 호출
Dictionary<int, string> map = new Dictionary<int, string>();
map[7] = "seven"; // (E) 키(int) 해시/비교
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.