2011-08-16 3 views
8

Action<T> 값을 설정할 때 조건문에이 이상한 문제가 발생합니다. 정상적인 방법 인 if을 사용하여 해결하기가 쉽기 때문에이 문제를 해결하는 방법을 모르겠습니다.조건부 명령문, 일반 대리자 불필요한 캐스트

public class Test 
{ 
    public bool Foo { get; set; } 
    public Action<bool> Action { get; set; } 

    public void A() 
    { 
     Action = Foo ? B : C;//Gives compiler error 
    } 

    public void B(bool value) 
    { 

    } 

    public void C(bool value) 
    { 

    } 
} 

이 메시지

'방법 그룹'과 '방법 그룹'사이에 암시 적 변환이 없습니다와 나에게 컴파일러 오류를 제공합니다 :

여기 내 문제입니다.

나는 이것이 왜 불법인지 알 수 없기 때문에 이상합니다. 왜 캐스팅이 필요로

public void A() 
    { 
     Action = Foo ? (Action<bool>) B : C; 
    } 

그래서 어쩌면 당신이 질문을 읽을 수 있습니다 : 그런데

는 아래의 구문은 (보기의 컴파일러의 관점에서)이 유효 만들 것인가?

답변

2

두 개의 유사한 개념이 있습니다.

A) 방법 그룹. 메서드 그룹은 이름이 같은 하나 이상의 C# 메서드입니다. 주로 컴파일러에서 사용되는 추상화입니다. 메소드 그룹을 넘길 수는 없습니다. 메서드 그룹을 사용하여 수행 할 수있는 작업은 메서드를 호출하거나 대리 그룹을 만드는 것입니다. 형식 시그니처가 일치하면 메서드 그룹에서 암시 적으로 대리자를 만들 수 있습니다.

B) 대리인. 당신은 대의원이 무엇인지 압니다. 특정 형식 시그니처를 가지며 직접 메서드를 참조합니다. 그것을 호출하는 것뿐만 아니라, 그것을 전달하고이를 일류 객체로 취급 할 수 있습니다.

첫 번째 예에서는 표현식이 한쪽에 메서드 그룹 B을, 다른쪽에 다른 메서드 그룹 C을 반환합니다. 삼항 연산자는 양쪽에 같은 유형을 반환해야하지만 어느쪽에 캐스트해야할지 모릅니다. 결과를 (Action<bool>)에 지정한 변수 유형은 표현식의 유형을 판별하지 않습니다. 그래서 모호합니다.

두 번째 예제에서는 합법적으로 메서드 그룹 BAction<bool> 대리자로 삼항 연산자의 한쪽에 캐스팅합니다. 표현식을 명확히하려는 과정에서 컴파일러는 각면을 다른면의 유형으로 캐스팅하려고합니다. 메서드 그룹 CAction<bool>으로 성공적으로 캐스팅 할 수 있으므로 제대로 수행되고식이 적합합니다.

-1

동작은 특정 대리자 클래스이며 유사한 서명이있는 일반 대리인에게 /에서 사용 가능한 암시 적 변환이 없습니다.

+0

나는 C# 컴파일러가 그것을 확인하기에 충분히 똑똑하다고 생각했다. –

1

BC은 실제로는 대리인이 아닙니다. 그것들은 메소드 그룹이며, 암시 적으로 델리게이트 (특히 Action<bool>)로 변환 될 수 있습니다. 그러나 이것은 동일한 것이 아닙니다.

BC은 현재 형식화되지 않은 메서드 그룹이므로 컴파일러는 형식이 무엇인지 알아낼 수 없으므로 두 분기에서 일관성이 있어야합니다. 그것이 당신에게 알려주 듯이, 그들 사이의 암묵적인 변환은 없습니다.

뿐만 아니라, 그것은 (또는 적어도 하지 않음) 할당 연산자의 다른 측면을 살펴 수없고 "아, Action<bool>해야한다"말한다.

당신이 캐스트를 추가 할 때, 왼쪽 지점 식의 유형은 Action<bool>이되고, 은 다른 쪽의 방법 그룹과 그 위임, 그래서 컴파일러 사이의 암시 적 변환이 다시 행복이 : 유형 전체 식은 Action<bool>입니다.

0

나는, Eric will again tell me, that my reasoning is slightly incorrect을 생각하지만, 유형이없는, 그것은 객체 어쨌든 시도하고 예를 B를 들어,

하는 방법 그룹 :-) 자신의 보정을 희망하지 않은 나는 줄 것이다 (B.GetType()는 컴파일되지 않습니다).
쉽게 형식으로 변환 할 수 있으므로 암시 적 캐스트가 존재하는 것입니다. 샘플 :

Action<bool> a = B; // implicit cast taking place. 

그러나, 링크 된 질문에서 볼 수 있듯이, 삼항 표현은 반환 유형을 찾으려고 그 표현식 매치의 두 부분. 나중에 Action<bool>으로 변환해야한다는 것을 모릅니다.메서드 그룹은 그 자체로 형식이 없으므로 형식 그룹 간에는 변환이없고 BC으로 변환 할 수 없으므로 컴파일러에서 불만을 토로합니다.

터너 리 표현식의 부분을 Action<bool>으로 형변환하면 반환 형식이 해당 형식이어야하며 3 진 표현식의 다른 부분이 해당 형식의 암시 적 캐스트를 지원하는지 여부를 확인합니다. 이 경우 코드가 컴파일됩니다.