2013-06-20 1 views
12

C#에서 모든 대리자 형식은 동일한 서명을 갖고 있더라도 서로 호환되지 않습니다. 예를 들면 다음과 같습니다.모든 대의원 유형이 서로 호환되지 않는 이유는 무엇입니까?

delegate void D1(); 
delegate void D2(); 

D1 d1 = MethodGroup; 
D2 d2 = d1;       // compile time error 
D2 d2 = new D2 (d1);     // you need to do this instead 

이 동작 및 언어 디자인 결정의 근거는 무엇입니까?

+2

추론 할 수는 없지만 대리인은 원래 언어 기능이었습니다. 그 이후로 그들은 [Actions] (http://msdn.microsoft.com/en-us/library/system.action.aspx) 및 [Funcs] (http://msdn.microsoft.com/)라는 람다 메서드를 추가했습니다. en-us/library/bb534960.aspx) 같은 문제가 발생하지 않습니다. – Brandon

+0

@ 브랜든 뭐라고 요? 람다는 델리게이트 (또는 표현식 트리)로 변환되고'Action'과'Func's *는 단지 델리게이트 타입이므로 똑같은 규칙을 따릅니다. – svick

+0

대리인 호출도 런타임에 확인됩니다. 중요한 종류의 최적화 인 최적화되었지만 엄격한 유형 ID 만 지원됩니다. 빨리. –

답변

23

In C# all delegate types are incompatible with one another, even if they have the same signature. What is the reasoning behind this behaviour and language design decision?

첫째을 :

delegate void D1(); 

약처럼 뭔가 컴파일됩니다. 대리자의 구조형 입력, 즉 서명에 의한 일치는 자주 요청되는 기능이며 Func<int, bool>Predicate<int>을 서로 자유롭게 할당 할 수없는 것 같습니다.

내가 이해할 때 결정을 내리는 추리 - 그리고 C# 팀을 시작하기 전에 약 6 년 전에이 결정이 내려 졌음을 서두르지 만, 이있는 대리 유형이있을 것이라는 기대가있었습니다. 의미. 같은 인자가있을 때 "순수"함수를 생산하고 부작용을 소모하지 않는 기능이며, 인수 이외의 어떠한 정보도 소비하지 않으며, 일관성있는 값을 반환

AnyFunction<int, int> af = x=> { Console.WriteLine(x); return x + y; }; 
PureFunction<int, int> pf = af; 

: 당신은이 유형의 오류가되고 싶어요 . 분명히 af은 두 개 이상 실패하므로 암시 적 변환으로 pf에 할당 할 수 없습니다.

그러나 의미 론적 인 대의원 유형은 결코 발생하지 않았으므로 지금은 다소 잘못된 점이 있습니다.

+1

나는 그 용어 '* misfeature *'를 기억해야 할 것이다. –

+1

에릭 리 퍼트 (Eric Lippert)보다 더 많은 찬성으로 답을 얻은 짧은 시간을 나는 좋아할 것입니다. –

15

기본적으로 컴파일러가 두 클래스를 작성하기 때문입니다. 같은 이유로 당신이 할 수 없습니다

class A {} 
class B {} 

void Main() 
{ 
    A a = new A(); 
    B b = a; 
} 
예를 들어

, 다음 코드

void Main() {} 

delegate void D(); 
class C {} 

일리노이 코드는 다음과 같습니다

D.Invoke: 

D.BeginInvoke: 

D.EndInvoke: 

D..ctor: 

C..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: ret   
2

위임 아무것도하지만, 또 다른입니다 유형. 동일한 이유로 class A {}class B {}은 호환되지 않습니다. 나는 런타임 및 언어 디자이너의 많은 사람들이이 결정을 후회한다는 말을 공정하다고 생각,

class D1 : MulticastDelegate { .... } 
관련 문제