【问题标题】:Static extension methods supporting member constraints支持成员约束的静态扩展方法
【发布时间】:2010-09-09 22:54:26
【问题描述】:

我需要实现一个静态扩展方法,支持对一些基本基本类型(如整数、浮点数等)的成员约束。这是我的有符号整数代码:

module MyOperators =
    let inline foo (x : ^T) = (^T : (static member Foo : ^T -> int) (x)) 

    type System.Int32 with 
        static member Foo(x : Int32) = 7 // static extension

测试代码:

open MyOperators    
let x = foo 5 // x should be 7

但是编译器报错:

“System.Int32”类型不 支持任何名为 'Foo' 的运算符

我在这里缺少什么?谢谢!

【问题讨论】:

  • 如果我对你的理解正确的话,我认为即使你能做到这一点,这也不是一个特别好的主意。修补基本的语言机制总是让我觉得是一种反模式。想一想这样一个事实,除了您之外的其他人可能在未来的某个时候必须处理此代码。当您有一段时间没有使用它时,您甚至可能不得不在将来的某个时候自己维护此代码。对内在类型的修改可能会导致几个“WTF?”时刻。

标签: f# extension-methods type-constraints


【解决方案1】:

F# 中的静态成员约束永远不会找到“扩展方法”,它们只能看到类型的内在方法(以及 F# 语言规范中提到的一些特殊情况)。

也许您可以改用方法重载?你的最终目标是什么?

【讨论】:

  • 谢谢。最终目标是将我自己的一组内在函数添加到 FSharp.Core.Operators,例如三角函数等。
【解决方案2】:

F# 的静态类型约束不适用于扩展方法。扩展方法不能在编译时静态检查,即使这样,您也可以有多个 Int32::Foo 定义(取决于您导入的命名空间)。

不幸的是,要解决您的问题,您可能不得不求助于反射。

【讨论】:

  • 我不认为这在技术上是不可行的——扩展方法在编译时静态检查(当你调用它们时),所以它们也可以被成员约束接受。不支持这是有道理的,但应该可以......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多