2011-10-20 68 views
0

爲什麼不編譯下面的代碼?這是一個編譯器錯誤還是語言功能?什麼是最好的解決方法?仿製藥的故障

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()轉換爲let綁定並刪除<'T>以另一個我不喜歡的編譯器警告結束。我發現的唯一wokaround是將GetTypedObject <'T>()移入基類並公開。在此先感謝...

回答

3

由於類型推斷工作頂部至底部, 遇到 GetTypedObject返回 int它甚至達到了該方法的定義,並發現它應該是通用的 之前。 (正如布賴恩指出,成員之前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() = 
    member this.GetTypedObject<'T>() = 
     Unchecked.defaultof<'T> 

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

這裏有一個解決方法:

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> 

成員的簽名會首先讀取,那麼所有的讓利和成員當涉及到類型推斷的順序時。通過將返回類型放入聲明簽名中,它就變得可見。

+0

謝謝。無法想象這個解決方案可以這麼簡單:) – Alexander