7. record 의 값 의미론(value semantics)과 with 식
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// ============================================================================
// [언어 내부동작 문제] C# - record 의 값 의미론(value semantics)과 with 식
// ----------------------------------------------------------------------------
// 주제: record(참조형)와 record struct(값형)가 컴파일러 생성 멤버(Equals/GetHashCode/
// ToString/Deconstruct/복제)로 어떻게 "값 동등성" 을 갖는지, with 식이 무엇을
// 하는지, 일반 class 와 무엇이 다른지.
//
// 과제(코드를 고치는 문제가 아니라, 출력과 내부 동작을 예측·설명하는 문제):
// 1) (1)~(6) 각 출력을 예측하라.
// 2) record 가 컴파일러로부터 자동 생성받는 멤버들이 무엇인지, 그 결과 == 와
// ReferenceEquals 의 차이가 어떻게 나타나는지 설명하라.
// 3) 'a with { Y = 9 }' 는 내부적으로 무슨 일을 하는가(복제 + 일부 변경)? a 는
// 바뀌는가?
// 4) HashSet<Point> 에 값이 같은 a, b 를 넣으면 원소 개수가 왜 그렇게 되는가?
// 5) record class 와 record struct 의 동등성/복사/with 동작 차이를 설명하라.
// (먼저 직접 예측을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
using System;
using System.Collections.Generic;
record Point(int X, int Y);
record struct Vec(int X, int Y);
class PlainPoint
{
public int X, Y;
public PlainPoint(int x, int y) { X = x; Y = y; }
}
class Program
{
static void Main()
{
var a = new Point(1, 2);
var b = new Point(1, 2);
Console.WriteLine(a == b); // (1)
Console.WriteLine(ReferenceEquals(a, b)); // (2)
Console.WriteLine(a.GetHashCode() == b.GetHashCode()); // (3)
var c = a with { Y = 9 }; // 복제 후 Y 만 변경
Console.WriteLine(a); // (4) ToString
Console.WriteLine(c); // (5) ToString
var set = new HashSet<Point> { a, b };
Console.WriteLine(set.Count); // (6)
// 대조용: 일반 class 는 어떻게 다른가?
var p = new PlainPoint(1, 2);
var q = new PlainPoint(1, 2);
Console.WriteLine(p.Equals(q)); // 참고
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.