2017-09-26 4 views
2

다음 코드를 실행하면 RuntimeBinderException: 'object' does not contain a definition for 'SetIt'이 표시됩니다. 나는 varthing을 전환하면개인 내부 클래스에서 동적 오류

public interface IInput { } 

public interface IThing<in TInput> 
{ 
    void SetIt(TInput value); 
} 

public class ThingMaker 
{ 
    private class Thing<TInput> : IThing<TInput> 
     where TInput : IInput 
    { 
     public void SetIt(TInput value){} 
    } 

    private class Input : IInput {} 

    public IThing<IInput> GetThing() 
    { 
     return new Thing<IInput>(); 
    } 

    public IInput GetInput() 
    { 
     return new Input(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var thingMaker = new ThingMaker(); 

     var input = thingMaker.GetInput(); 
     dynamic thing= thingMaker.GetThing(); 

     thing.SetIt(input); 
    } 
} 

는 그것을 잘 작동합니다. 이렇게 명확하게, thing에는 SetIt가있다. 동적 사용시 어떻게 실패합니까? 으로 작동하는 어떤 것이 또한 dynamic 일 때 일 것이 아닌가?

내가 공개 할 때 작동하기 때문에 개인 내부 클래스 인 Thing<TInput>과 관련이 있다고 생각합니다.

class A 
{ 
    class B 
    { 
     public void M() { } 
    } 

    public static object GetB() { return new B(); } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic o = A.GetB(); 

     o.M(); 
    } 
} 

제네릭 및 인터페이스 그냥 산만 있습니다

답변

1

여기에 문제의 간단한 예입니다.

B (또는 귀하의 경우 Thing<IInput>)은 개인 클래스이므로 호출 사이트에서 실제 유형으로 확인할 수 없습니다. dynamic은 단순히 object 변수이지만 런타임까지 컴파일이 연기 된 것을 상기하십시오. 달리 할 수없는 실행 시간에 작업을 수행 할 수 있도록하기위한 것이 아니며 "할 수 없다"는 호출 사이트의 액세스 가능 유형에 따라 판단됩니다 (이 예 : object).

런타임 바인더에 관한 한 유형은 단순히 object입니다 (따라서 object에 원하는 구성원이 포함되어 있지 않음을 알리는 오류 메시지가 표시됨).

물론 이론적으로는 dynamic이 다르게 구현되었을 수 있으며 유효한 유형을 더 자세히 검색 할 수 있습니다. 개체를 개체에 바인딩하는 목적으로 처리 할 수 ​​있습니다 (예 : 구현 된 인터페이스 객체의 실제 유형이 아니라). 그러나 이것은 구현 방법이 아니며 원래의 디자인과 구현면에서 물론, dynamic을 사용하는 코드의 런타임 비용면에서 훨씬 더 많은 비용이 들었을 것입니다.

관련 읽기 (틀림없이 중복) :

Is this a bug in dynamic?
Is this a hole in dynamic binding in C# 4?