48. dynamic 과 DLR: 런타임 바인딩과 콜사이트 캐시

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 주제: dynamic 과 DLR(Dynamic Language Runtime)의 내부 동작 — 런타임 바인딩과
//       콜사이트 캐시(call site caching).
//
// 과제:
//   1) 아래 프로그램의 표준출력(L1~L5)을 정확히 예측하라.
//   2) ViaStatic 과 ViaDynamic 이 같은 인자(new Dog())에 대해 왜 다른 오버로드를
//      고르는지 설명하라(정적 바인딩 vs 런타임 바인딩).
//   3) x.Bark() / x.Meow() 가 각각 어떻게 처리되는지, DLR 콜사이트가 무엇을 캐시하는지 설명하라.
//   (내부 동작 설명은 answer.md 에만. 여기서는 예측만.)

using System;

class Animal
{
    public virtual string Kind() => "Animal";
}

class Dog : Animal
{
    public override string Kind() => "Dog";
    public string Bark() => "woof";
}

class Program
{
    static string Ov(Animal a) => "Ov(Animal)";
    static string Ov(Dog d)    => "Ov(Dog)";

    static string ViaStatic(Animal a) => Ov(a);    // 인자 정적 타입 = Animal
    static string ViaDynamic(dynamic d) => Ov(d);  // 인자 정적 타입 = dynamic

    static void Main()
    {
        Animal a = new Dog();
        dynamic x = new Dog();

        Console.WriteLine(a.Kind());             // L1
        Console.WriteLine(ViaStatic(new Dog())); // L2
        Console.WriteLine(ViaDynamic(new Dog()));// L3
        Console.WriteLine(x.Bark());             // L4

        try
        {
            Console.WriteLine(x.Meow());         // 존재하지 않는 멤버
        }
        catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
        {
            Console.WriteLine("RuntimeBinderException"); // L5
        }
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.