2011-10-20 2 views
0

왜 다음 코드가 컴파일되지 않습니까? 그것은 컴파일러 버그 또는 언어 기능입니까? 가장 좋은 해결 방법은 무엇입니까?generics 관련 문제

type A() as this = 
    let a = this.GetTypedObject<int>() // a 
    let b = this.GetTypedObject<string>() // b 

    member this.GetTypedObject<'T>() = 
     Unchecked.defaultof<'T> 

Unchecked.defaultof < 'T>는 단지 어떤 함수 또는 생성자 콜 대신 사용될 수있는, 예를 들어 사용된다.

컴파일러는 코드가 라인 (a)에서 덜 일반화되고 라인 (b)을 컴파일하는 것을 거부합니다. 러시아어로되어 있기 때문에 정확한 컴파일러 메시지를 제공 할 수 없습니다. :).

GetTypedObject()를 바인딩 바인딩으로 바꾸고 < 'T>을 (를) 제거하면 다른 컴파일러 경고로 끝나고 나도 좋아하지 않습니다. 내가 찾은 유일한 wokaround는 GetTypedObject < 'T>()을 기본 클래스로 이동하고 public으로 만드는 것입니다. 사전에 감사 ... 형식 유추 이후

답변

3

는 위에서 아래로 작동 그것은 심지어 메서드 정의에 도달하고 일반적인해야한다 발견하기 전에 GetTypedObjectint을 반환 발견. (브라이언이 지적 하듯이, 회원 ... 이전 let 바인딩에 읽기 및 간단한 수정이 거기에 있습니다.) 나는 다음과 같은 불쾌한 오류 얻을 :

A use of the function 'GetTypedObject' does not match a type inferred elsewhere. The inferred type of the function is Test.A -> Microsoft.FSharp.Core.unit -> 'a. The type of the function required at this point of use is Test.A -> Microsoft.FSharp.Core.unit -> 'a This error may be due to limitations associated with generic recursion within a 'let rec' collection or within a group of classes. Consider giving a full type signature for the targets of recursive calls including type annotations for both argument and return types.

사용이 메서드 정의 후에 나타나는 경우를, 그것은 작동합니다.

type A() = 
    let getTypedObject() = Unchecked.defaultof<_> 
    let a : int = getTypedObject() // a 
    let b : string = getTypedObject() // b 

    member this.GetTypedObject<'T>() : 'T = getTypedObject() 
+0

감사합니다. 나를 위해 매력처럼 일했습니다. – Alexander

+0

그리고 훌륭한 설명! – Alexander

4

참고 단순히이 문제를 해결하기 위해 유형 약어를 추가 할 수 있습니다 :

type A() as this = 
    let a = this.GetTypedObject<int>() // a 
    let b = this.GetTypedObject<string>() // b 

    member this.GetTypedObject<'T>() : 'T = 
            //^^^^ 
     Unchecked.defaultof<'T> 

회원의 서명을 먼저 읽어 얻을 다음 모든하자 및 회원 여기

type A() = 
    member this.GetTypedObject<'T>() = 
     Unchecked.defaultof<'T> 

    member this.Test() = 
     let a = this.GetTypedObject<int>() // a 
     let b = this.GetTypedObject<string>() // b 
    () 

는 해결 방법입니다 시체, 형식 유추의 순서에 관해서. 반환 형식을 선언 서명에 넣으면이를 깡통에게 표시됩니다.

+0

감사합니다. 그 해결책이 이렇게 쉬울 수 있다고 상상할 수 없었습니다 :) – Alexander