이유 - c# 동적 클래스 생성




'동적'유형의 표현식이 동일한 실행 유형 시간의 비 동적 유형과 동일한 방식으로 런타임에서 작동해야합니까? (2)

다음 예제 프로그램을 생각해보십시오.

using System;
public delegate string MyDelegateType(int integer);

partial class Program
{
    static string MyMethod(int integer) { return integer.ToString(); }

    static void Main()
    {
        Func<int, string> func = MyMethod;

        // Scenario 1: works
        var newDelegate1 = new MyDelegateType(func);
        newDelegate1(47);

        // Scenario 2: doesn’t work
        dynamic dyn = func;
        var newDelegate2 = new MyDelegateType(dyn);
        newDelegate2(47);
    }
}

첫 번째 예상대로 작동합니다 - MyDelegateType 변환 성공합니다. 그러나 두 번째 오류 메시지는 RuntimeBinderException 을 발생시킵니다.

암시 적으로 'System.Func <int, string>'형식을 'MyDelegateType'으로 변환 할 수 없습니다.

이 동작을 허용하는 C # 사양에는 무엇이 있습니까? 아니면 Microsoft의 C # 컴파일러에있는 버그입니까?


Timwi를 잘 잡습니다.

동적 메서드 그룹에 대한 지원은 약합니다. 예를 들어,이 간단한 경우를 생각해보십시오.

class C
{
  public void M() {}
}

class P
{
    static void Main()
    {
        dynamic d = new C();
        C c = new C();
        Action a1 = c.M; // works
        Action a2 = d.M; // fails at runtime

dM 은 동적 런타임에 의한 속성 get (또는 필드 액세스)으로 해석되며 메소드 그룹으로 해석되면 런타임에 실패합니다.

당신의 경우에도 똑같은 일이 일어나고 있습니다, 그것은 조금 더 모호합니다. 당신이 MyDelegate x = new MyDelegate(someOtherDelegate); 라고 말할 때 MyDelegate x = new MyDelegate(someOtherDelegate); 마치 MyDelegate x = someOtherDelegate.Invoke; 라고 말한 것처럼 컴파일러에서 처리됩니다 MyDelegate x = someOtherDelegate.Invoke; . 동적 런타임 피스는 해당 변환 작업을 수행 할 수 없다는 사실을 알지 못합니다. .Invoke 표현식의 .Invoke 부분의 결과 인 메소드 그룹을 해결할 수 없습니다.

이 동작을 허용하는 C # 사양에는 무엇이 있습니까? 아니면 Microsoft의 C # 컴파일러에있는 버그입니까?

이 스펙은 런타임 오류 여야하며 런타임에 올바르게 처리되어야한다는 것을 암시하지 않습니다. 명확하게 구현은 그렇게하지 않습니다. 구현의 단점이지만, 우리는 의도적으로 당신이 발견 한 행동을했기 때문에 이것을 "버그"라고 부르지 않을 것입니다. 우리는 이러한 종류의 표현식이 정확하게 작동하도록하는 자원이 없었기 때문에 오류로 남겨 두었습니다. 동적 런타임에서 메소드 그룹을 표현할 수있는 좋은 방법을 얻은 경우 구현할 수 있습니다.

마찬가지로 동적 코드에는 "이 동적 인 것은 런타임에 매개 변수의 유형이 결정되는 람다 식입니다"라는 개념을 나타낼 방법이 없습니다. 우리가 미래에 그들을 대표 할 수있는 좋은 방법이 있다면, 우리는 그 일을 할 것입니다.

Sam은 2008 년에 이것에 대해 조금 이야기했습니다. 그것에 그의 기사를보십시오 :

http://blogs.msdn.com/b/samng/archive/2008/11/02/dynamic-in-c-ii-basics.aspx


나는이 제한에도 뛰어 들었다. 에릭 리 퍼트 (Eric Lippert)보다 왜 더 나은지 대답 할 수는 없지만 직접적인 해결책이 있습니다.

 var newDelegate2 = new MyDelegateType(x => dyn(x));

그것은 암시 적으로 대리자에서 정적 서명을 가져오고 동적 호출은 더 이상 정보없이 작동합니다. 위임자와 보너스로 동적 호출 가능 객체에서 작동합니다.





dynamic