f# - 如何在 F# 中扩展 System.DateTime?

标签 f# extension-methods

我想按以下方式扩展 DateTime:

[<AutoOpen>]
type System.DateTime with
  member this.floor (interval: TimeSpan) =
    this.AddTicks(-(this.Ticks % interval.Ticks))

  member this.ceiling (interval: TimeSpan) =
    let overflow = this.Ticks % interval.Ticks
    if overflow = 0 then this else this.AddTicks(interval.Ticks - overflow)

  member this.round (interval: TimeSpan) =
    let halfIntervalTicks = (interval.Ticks + 1) >>> 1
    this.AddTicks(halfIntervalTicks - ((this.Ticks + halfIntervalTicks) % interval.Ticks))

基于 aj.toulan 的 C# 答案:DateTime Round Up and Down

但这行不通;显然我应该使用一个模块,但是如何获得“这个”部分呢?正确的语法是什么?

我收到此错误:

[FS0644] Namespaces cannot contain extension members except in the same file and namespace declaration group where the type is defined. Consider using a module to hold declarations of extension members.

最佳答案

根据错误消息判断,我假设您在命名空间内有该声明,如下所示:

namespace N

type System.DateTime with
    ...

如果是这样,那么我的第一个问题是:为什么首先需要命名空间?使用模块代替!模块在 F# 中更惯用,让您可以做更多事情:

module N

type System.DateTime with
    ...

但是,如果由于某种原因您必须拥有命名空间,您仍然可以通过使用错误消息本身中提供的建议来完成此操作:将扩展放入模块中!

namespace N

module M =    
    type System.DateTime with
        ...

当然,现在您还必须open该模块在使用站点:

open N
open M  // <-- extra open

... DateTime.Now.floor ...

但是您也可以通过为该模块指定 [<AutoOpen>] 来避免这种情况。属性:

namespace N

[<AutoOpen>]
module M =    
    type System.DateTime with
        ...

现在使用站点只能打开命名空间:

open N

... DateTime.Now.floor ...

另外,请注意 [<AutoOpen>]关于类型扩展是没有意义的。类型扩展始终是打开的,这就是它们的要点,您不需要显式打开它们或拥有 AutoOpen属性。

关于f# - 如何在 F# 中扩展 System.DateTime?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64514115/

相关文章:

list - F# 列表中的 Task.WaitAll

f# - F#(和 .NET)中的浮点精度

ios - 在 Swift 中使用 Bool 的 View Controller 扩展

c# - 为什么 EnumerableRowCollection<DataRow>.Select() 不能这样编译?

unit-testing - 您如何使依赖于扩展方法的方法可测试?

c# - 查看模型到领域模型,在哪里测试映射?

c# - 具有动态命名参数的扩展方法

.net - DotNumerics、AlgLib、dnAnalytics、Math.net、F# for Numerics、Mtxvec?

f# 可观察的 fork 和副作用

excel - 将 Excel 数据导入 F#