如何写一个泛型类型的扩展方法,其中一个类型变量必须是字符串?

问题描述:

我特别想写的扩展方法对于这种类型的:如何写一个泛型类型的扩展方法,其中一个类型变量必须是字符串?

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

我没有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

非常感谢!我甚至没有关闭 –

@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# - 只有代码 - 让 - 束缚函数更适用于方法,因为它们作为类型的固有部分没有意义,并且来自属性的噪声更少。