11. Equals/GetHashCode 계약과 Dictionary/HashSet 키
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 주제: Equals/GetHashCode 계약과 Dictionary/HashSet 키
//
// 과제: 아래 세 경우에서 출력(found1/found2/found3)을 예측하고 이유를 설명하라.
// 1) [NoOverride] Equals/GetHashCode 를 재정의하지 않은 "참조 형식"을 키로
// 쓰면, 값이 같은 다른 인스턴스로 조회가 되는가?
// 2) [Mutable] 값 기반 Equals/GetHashCode 를 가진 키를 사전에 넣은 뒤 그
// 키의 필드를 바꾸면 어떻게 되는가? 왜 그런가?
// 3) [Struct 기본 해시] GetHashCode/Equals 를 재정의하지 않은 "값 형식"을
// HashSet 키로 쓰면 값으로 조회되는가? 그 기본 구현의 비용은?
// 추가: Equals/GetHashCode "계약"은 무엇이며, 왜 둘을 함께 재정의해야 하는가?
using System;
using System.Collections.Generic;
public class NoOverride // Equals/GetHashCode 재정의 없음
{
public int Id;
public NoOverride(int id) { Id = id; }
}
public class ValueKey // 값 기반 재정의 O, 하지만 가변(mutable)
{
public int Id;
public ValueKey(int id) { Id = id; }
public override bool Equals(object o) => o is ValueKey v && v.Id == Id;
public override int GetHashCode() => Id;
}
public struct Coord // GetHashCode/Equals 재정의 없음(기본 ValueType)
{
public int X, Y;
public Coord(int x, int y) { X = x; Y = y; }
}
public static class Program
{
public static void Main()
{
// 1) 참조 형식, 재정의 없음
var d1 = new Dictionary<NoOverride, string>();
d1[new NoOverride(1)] = "alice";
bool found1 = d1.ContainsKey(new NoOverride(1)); // (A) 예측?
Console.WriteLine(found1);
// 2) 값 기반 재정의 O, 넣은 뒤 키 변경
var d2 = new Dictionary<ValueKey, string>();
var k = new ValueKey(2);
d2[k] = "bob";
k.Id = 999; // (B) 사전에 든 키를 변경
bool found2 = d2.ContainsKey(k); // 예측?
Console.WriteLine(found2);
// 3) 값 형식, 기본 해시
var set = new HashSet<Coord>();
set.Add(new Coord(3, 4));
bool found3 = set.Contains(new Coord(3, 4)); // (C) 예측?
Console.WriteLine(found3);
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.