2017-03-17 114 views
3

我特別想寫的擴展方法對於這種類型的:如何寫一個泛型類型的擴展方法,其中一個類型變量必須是字符串?

type Frame<'TRowKey, string when 'TRowKey : equality> with 
    member frame.someMethod = 
    // code 

與該代碼,我得到這個錯誤:

Unexpected identifier in type name. Expected infix operator, quote symbol or other token.

更換stringString給出了相同的結果。

來自Deedle庫的原始類型爲Frame<'TRowKey, 'TColumnKey (requires equality and equality)>

+0

請注意,類型約束必須寫在左側,請參閱我的更新答案。 – Gustavo

回答

2

我沒有Deedle測試這個代碼,但是你應該使用.NET擴展方法:

open System 

[<Runtime.CompilerServices.Extension>] 
module Extensions = 
    [<Runtime.CompilerServices.Extension>] 
    let someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body 

這是scrwtp電話「的慣用方式」以同樣的方式(我不喜歡進入關於idomaticity的討論),但同時它將從C#作爲擴展方法工作。

如果你想使用它從F#以及一個擴展,它必須聲明爲類型:所以現在你可以鍵入和智能將

[<Runtime.CompilerServices.Extension>] 
type Extensions = 
    [<Runtime.CompilerServices.Extension>] 
    static member someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body 

只顯示分機如果其第二個參數是一個字符串。

+1

它可能需要是佔位符類型上的靜態成員,而不是綁定的模塊。 – scrwtp

+1

@scrwtp是的,如果你想從F#中使用它作爲擴展。我剛剛添加了其他版本。 – Gustavo

+0

非常感謝!我甚至沒有關閉 –

5

@Gustavo瞭如何獲得它的擴展方法工作的全面的答案。但是,如果你不具備這是一個擴展方法(如C#互操作)特別強的原因,你可能只是去用一個簡單的函數:

type Frame<'row, 'col> = { row: 'row; col: 'col } 

module Frame = 
    let restricted (frame: Frame<'row, string>) = frame 

Frame.restricted { row = 3; col = "test" } // compiles 
Frame.restricted { row = 3; col = 5 }  // doesn't 

這就是我會考慮一個更清潔的方式書寫時F# - 只有代碼 - 讓 - 束縛函數更適用於方法,因爲它們作爲類型的固有部分沒有意義,並且來自屬性的噪聲更少。

相關問題