2011-11-23 4 views
21

다음 F # 코드는 기본 클래스와 하위 클래스를 선언합니다. 기본 클래스는 가상 메소드 'Test'를 기본 구현으로 사용합니다. 하위 클래스는 기본 클래스 메서드를 재정의하고 새 오버로드 된 'Test'메서드를 추가합니다. 이 코드는 잘 컴파일되고 하위 'Test'메소드 중 하나에 액세스 할 때 아무런 문제가 없습니다.C#에서 재정의되고 오버로드 된 F # 메서드를 확인할 수 없습니다.

F # 코드 :

var result = td.Test(3); <- No overload for method 'Test' takes 1 arguments

전체 C# 코드 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Client 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     var td = new OverrideTest.Descendant(); 
     var result = td.Test(3); 
     Console.WriteLine(result); 
     Console.ReadKey(); 
    } 
    } 
} 
컴파일 오류에 C#을 결과에서 '테스트'의 자손의 재정의를 호출하려고 시도하지만

module OverrideTest 
    [<AbstractClass>] 
    type Base() = 
    abstract member Test : int -> int 
    default this.Test x = x + 1 

    type Descendant() = 
    inherit Base() 
    override this.Test x = x - 1 
    member this.Test (x, y) = x - y 

,

이상한 점은 VisualStudio의 Intellisense는 두 가지 오버로드 된 함수를보고, 둘 다 올바른 서명. 빌드가 실패하기 전에 경고 또는 오류를 표시하지 않으며 이후에만 해당 행을 강조 표시합니다.

이 시나리오를 C#에서 완전히 다시 구현했지만 동일한 문제가 발생하지 않았습니다.

누구에게 무슨 일이 일어나고 있는지 아이디어가 있습니까? 또는 단순히 Test2(x,y) 이름을 변경 - -

+0

방출 된 IL을 두 언어로 비교 했습니까? – Oded

+0

C# 코드에서 메서드를 호출하기 전에 기본 클래스로 업 캐스트하면 어떻게됩니까? – Brian

+0

@ 브라이언 : 그건 작동합니다. – Daniel

답변

17

아니오 당신이 Descendant 유형에서 Test(x,y) 멤버를 생략하면 것을 알고 의심 다음 C# 코드를 컴파일하고 예상대로 실행됩니다. Test(x,y) 방법에는 hidebysig 속성이 없다는 것을

.method public hidebysig virtual 
    instance int32 Test (
     int32 x 
    ) cil managed ... 

.method public 
    instance int32 Test (
     int32 x, 
     int32 y 
    ) cil managed ... 

주의 사항 : 원래 Descendant 유형에 대해 생성 된 IL 보면

는 단서를 제공합니다.

ECMA CLI specification은 약 hidebysig이다. (섹션 15.4.2.2는 굵게 강조 내이다.)

hidebysig is supplied for the use of tools and is ignored by the VES. It specifies that the declared method hides all methods of the base class types that have a matching method signature; when omitted, the method should hide all methods of the same name, regardless of the signature.

은 그래서, F # 컴파일러는 hidebysig 속성을 생략 상기 Test(x,y) 방법 Test라는 다른 방법을 숨기는 것을 의미한다. hidebysig은 "도구 사용 용"일 뿐이지 만 C# 컴파일러는이를 사용하는 도구 중 하나입니다!

이것은 F # 컴파일러에서 버그가 될 수있는 것처럼 보입니다.하지만 F # 스펙을 본 적이 없으므로 항상 허용/지정 동작이 가능합니다.

+0

+1 : '같은 이름'을 파악하기 위해 몇 번 읽어야했습니다. IMO 문장의 마지막 부분은 ** BOLD **이어야합니다. – leppie

+0

버그가 _ _ _ 있습니다. 권리? – Daniel

+0

@Daniel : '은신처'를 생략해야하는 이유를 생각할 수 없습니다. (나는 이것에 대해 결코 알지 못했다) – leppie

관련 문제