2014-03-06 130 views
4

的類別:可選參數

type NotAbstract() = 
    member this.WithOptionalParameters (x, ?y) = 
     let y = defaultArg y 10 
     x + y 

具有以下類型簽名:

type NotAbstract = 
    class 
    new : unit -> NotAbstract 
    member WithOptionalParameters : x:int * ?y:int -> int 
    end 

然而,這不起作用:

[<AbstractClass>] 
type AbstractExample() = 
    abstract WithOptionalParameters: int * ?int -> int /// Ouch... 

type NotAbstract() = 
    inherit AbstractExample() 
    override this.WithOptionalParameters (x, ?y) = 
     let y = defaultArg y 10 
     x + y 

怎麼寫具有可選參數的函數抽象定義中的正確類型簽名?我沒有找到任何提示here

PS:據我所知,(類似)的結果可能與polymorphism

+0

F#方式是使用Option類型而不是(更原始的)可空類型。 –

回答

6

聲明的參數作爲選項類型並沒有真正的參數可選。

NotAbstract().WithOptionalParameters(2) 
// This expression was expected to have type 
//  int * Option<int>  
// but here has type 
//  int  

spec §8.13.6有它:

在簽名,可選參數如下所示: static member OneNormalTwoOptional : arg1:int * ?arg2:int * ?arg3:int -> int

在抽象成員簽名命名的可選參數,從而

[<AbstractClass>] 
type AbstractExample() = 
    abstract WithOptionalParameters: int * ?y:int -> int  

type NotAbstract() = 
    inherit AbstractExample() 
    override this.WithOptionalParameters (x, ?y) = 
     let y = defaultArg y 10 
     x + y 

NotAbstract().WithOptionalParameters(42) // val it : int = 52 
2

實現這應該工作:

[<AbstractClass>] 
type AbstractExample() = 
    abstract WithOptionalParameters: int * Nullable<int> -> unit 

In F#, there's no syntactical sugar for nullable types,所以雖然你可以聲明可空與?y語法,你不能這樣做類型。相反,你將不得不使用Nullable<T>

+0

s /聲明一個*值*可爲空/聲明一個值可選/? –

+0

要麼我誤解了原來的問題,要麼一路上犯了一些其他的認知錯誤,但我最終認爲這是解決方案。很明顯,正確的答案是polkduran提供的答案,但我認爲我只是在這裏留下我的答案,而不能幫助其他人...... –

+1

@Mark F#中的'?arg'語法沒有「使一個值可以爲空」。它將元組方法參數的元素聲明爲F#客戶端的可選參數。但是,非F#客戶端會將其視爲'FSharpOption <...>'。這與C#中的'Type'語法不同,它將值類型聲明爲可爲空值,這對所有CLI客戶端(包括F#)來說都是'可空的<...>'。這兩個概念之間沒有任何關係...... –

4

可選參數被編譯成Option類型,使用Option<int>代替?int

[<AbstractClass>] 
type AbstractExample() = 
    abstract WithOptionalParameters: int * Option<int> -> int  

type NotAbstract() = 
    inherit AbstractExample() 
    override this.WithOptionalParameters (x, ?y) = 
     let y = defaultArg y 10 
     x + y 
+0

謝謝,是的,這是真的。我編輯了你的答案,以修正我自己在'WithOptionalParameters'類型簽名中的錯誤,它實際上返回一個'int'。 – NoIdeaHowToFixThis

+0

@NoIdeaHowToFixThis好的感謝編輯,我不粘貼它之前檢查代碼。 – polkduran