2009-05-20 2 views
8

나는 정말로 문제가되지 않지만 조금 호기심을 자극하는 질문이 있습니다.C#의 모호한 호출에 대한 질문

두 개의 메소드가있는 클래스가 있습니다. 하나는 정적 메소드이고 다른 하나는 인스턴스 메소드입니다. 메서드는 같은 이름입니다. 'MyApp.BlockHeader.Peek (System.IO :

호출이 다음 메서드 나 속성 사이의 모호 : 내 프로젝트를 빌드 할 때

public class BlockHeader 
{ 
    public static BlockHeader Peek(BinaryReader reader) 
    { 
     // Create a block header and peek at it.   
     BlockHeader blockHeader = new BlockHeader(); 
     blockHeader.Peek(reader); 
     return blockHeader; 
    } 

    public virtual void Peek(BinaryReader reader) 
    { 
     // Do magic. 
    } 
} 

내가 말하는 오류가 발생합니다. BinaryReader를) ' 및 'MyApp.BlockHeader.Peek (System.IO.BinaryReader) '

나는 메소드 서명이 용 다운로드 것을 알고 똑같은 방법이지만 인스턴스 멤버에서 직접 정적 메서드를 호출하는 방법을 알 수는 없습니다.

나는 아주 좋은 이유가 있다고 생각하지만, 그 이유가 누구인지 아는 사람이 있습니까?

+3

J # 및 다른 언어가 인스턴스 멤버에서 정적 메서드를 호출 할 수 있기 때문에 이것이라고 생각합니다. CLR은 가장 낮은 공통 분모를 시행해야합니다. –

+0

J #이 이것을 허용하는지 몰랐습니다. 흥미 롭 군. – Patrik

+4

나는이 기괴한 발견. 이 사양은 _correct_라는 사양이 매우 분명합니다. 7.5.5 절을 보라.1,가는 비트 : "최선의 방법이 정적 방법 인 경우, 방법 그룹은 유형을 통한 단순한 이름 또는 구성원 액세스의 결과 여야합니다 ..."비트가 어떻게 발생하는지주의하십시오. "최상의"방법을 찾아 내십시오. "Bestness"는 정적을 검사하기 전에 FIRST로 명확하게 계산됩니다. 그러므로 bestness는 정적을 고려하지 않으며 귀하의 경우에는 최선의 방법을 결정할 수 없습니다. 따라서 모호성 오류. –

답변

9

C# 디자인의 일반적인 정책은 잠재적 인 모호성이있는 곳을 지정하도록 강요하는 것입니다. 모자를 떨어 뜨릴 때 물건이 고정되어 있는지 아닌지를 재검토 할 수있는 리팩토링 도구에 직면했을 때이 자세는 특히 이런 경우에 유용합니다. 당신은 이것과 같은 다른 많은 경우를 보게 될 것입니다 (가상 대치를 덮어 쓰거나 그림자를 새롭게하는 것 등).

일반적으로 혼동을 방지하기 위해이 유형의 공간을 제거하면 코드가 명확 해지고 집을 계속 지켜야합니다.

편집 : A good post from Eric Lippert discusses another reason for this ambiguity leading to the error you saw

+7

클래식 예제 (이 경우)는 Peek (...)를 호출하는 인스턴스 메서드입니다. 그거야. 알았어? 또는 BlockHeader.Peek? –

+0

당신의 요지를 봅니다. – Patrik

+0

1k, 잘 했어, 너는 나 한테 한밤중에 사 줄 수있어. –

2

나는 그것을 허용 할 기술적 인 이유가 없다고 생각하지만, 자신에서 프로그래머를 보호하기 위해 더욱 그렇게된다. 당신이 설명하는 상황이 허용된다면

public static void Main() 
{ 
    BlockHeader BlockHeader = new BlockHeader(); 
    BlockHeader.Peek(); 
} 

위의 예를 완벽하게 유효하지만, 그것을 읽을 것입니다 : 다음의 예를 고려? 눈 깜박 할 사이에 인스턴스 메서드 또는 정적 메서드가 호출되었는지 여부를 확인할 수 있습니까?

+0

너의 요점을 안다. 좋은 예입니다. – Patrik

4

다음은 C# 3.0 언어 사양에서 발췌 한 것입니다.

메서드의 서명은 메서드가 선언 된 클래스에서 고유해야합니다. 메소드의 서명은 메소드의 이름, 유형 매개 변수의 수, 매개 변수의 수, 수정 자 및 유형으로 구성됩니다. 메소드의 시그니처에는 리턴 유형이 포함되지 않습니다.

'정적'한정자는 서명의 일부가 아니므로이 고유 한 서명 규칙을 위반하는 것입니다.

나는 규칙의 이유를 모르지만,.