使用通用约束键入扩展名,不会引发错误,也不会执行预期的操作

时间:2016-10-13 03:44:28

标签: generics f# generic-constraints type-extension

请考虑使用F#4.0,.NET 4.6的以下代码段:

type X<'T> = Y of 'T

type XS = X<string>
type XI = X<int>

type X<'T when 'T :> string> with
    static member X = 2
    static member take (s: 'T) = s

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module XS =
    let foo = 10
    let create s = XS.Y s
    let test = XI.take 2    // expected only string allowed, XI.take should not exist

我希望尊重类型扩展名type X<'T when 'T :> string> with(在这种情况下,这意味着错误,因为string已被封存,或限制'Tstring }),或者引发语法错误。

更重要的是,我也可以使用以下语法,这将是普通类型定义中的语法错误(没有with):

type X<'T> when 'T :> string with
    static member X = 2
    static member take (s: 'T) = s

我的猜测是,在扩展名上只会忽略约束。这是设计的吗?或者它应该工作,如果是的话,怎么样?

当我尝试使用类型扩展并想知道我是否可以创建一组仅适用于特定具体类型的特定方法或更具限制的具体类型时(我也可以通过继承来完成) ,我知道。)

1 个答案:

答案 0 :(得分:3)

我认为编译器应该拒绝你的代码,但这里有一些观察结果:

  1. 请注意,如果您使用&#34; extrinsic&#34;扩展(例如,通过将定义和扩展放在不同的模块中 - 请参阅Type Extensions) - 在那里,编译器将扩​​展标记为错误。
  2. 如果您想要的是实例扩展方法仅显示类型参数的某些具体值,那么您可以使用C#风格的扩展方法(这也在上面的链接)。但是,由于C#不支持静态扩展成员,因此无法将此技巧应用于您的方案。