使用扩展方法覆盖F#中的静态属性 [英] Overriding static properties in F# with extension methods

查看:68
本文介绍了使用扩展方法覆盖F#中的静态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以在名称和类型签名与现有实例和静态方法相同的类型上定义F#扩展方法,以有效地覆盖这些方法的默认实现,但是我无法在静态属性上使用它.

F# extension methods can be defined on types with the same name and type signature as existing instance and static methods to effectively override the default implementation of these methods, however I can't get this to work on static properties.

尤其是,我正在尝试为 DateTime 创建一个扩展方法,该方法将返回更精确的时间,如下所示:

In particular, I'm trying to create an extension method for DateTime that returns a more precise time as follows:

#nowarn "51"

open System

module DateTimeExtensions =

    open System.Runtime.InteropServices

    [<DllImport("Kernel32.dll", CallingConvention = CallingConvention.Winapi)>]
    extern void private GetSystemTimePreciseAsFileTime(int64*)

    type System.DateTime with
        // example showing that static methods can be overridden
        static member IsLeapYear(_: DateTime) =
            printfn "Using overridden IsLeapYear!"
            true

        // more accurate UtcNow method (note: not supported by older OS versions)
        static member UtcNow =
            printfn "Using overridden UtcNow!"
            let mutable fileTime = 0L
            GetSystemTimePreciseAsFileTime(&&fileTime)
            DateTime.FromFileTimeUtc(fileTime)

但是,执行时的输出

open DateTimeExtensions
let _ = DateTime.IsLeapYear(DateTime.UtcNow)

就是

Using overridden IsLeapYear!

这表明静态方法"override"正在工作,但没有static属性.

which shows that the static method 'override' is working, but not the static property.

(注意:我使用的是F#4.0)

(Note: I'm using F# 4.0)

推荐答案

此陈述似乎不正确:

可以在具有相同名称和类型的类型上定义

F#扩展方法类型签名作为现有实例和静态方法有效覆盖这些方法的默认实现,但是我不能使它可以处理静态属性.

F# extension methods can be defined on types with the same name and type signature as existing instance and static methods to effectively override the default implementation of these methods, however I can't get this to work on static properties.

不,它们不会覆盖.

您可能会感到困惑,因为实际上您的 IsLeapYear 签名是错误的,它应该是一个整数,这就是为什么它起作用的原因,我的意思是您没有重写任何东西,只是添加了一个新的(扩展名)方法

You might be confused because in fact your signature of IsLeapYear is wrong, it should take an integer, that's why it works I mean you are not overriding anything, just adding a new (extension) method.

如果您尝试使用原始签名,则会发现它也不起作用:

If you try it with the original signature you'll see that it doesn't work either:

type System.DateTime with
    // example showing that static methods can NOT be overridden
    static member IsLeapYear(_: int) =
        printfn "Using overridden IsLeapYear!"
        false

> DateTime.IsLeapYear(2000);;
val it : bool = true

与静态属性扩展的行为一致.

Which is consistent with the behavior of the static property extension.

无论如何,我不确定为什么在设计语言时是否曾做出过这样的决定,所以决定不重写它.我认为这将是一个有趣的功能,如果有充分的理由不执行它,至少它应该发出警告,说由于该方法已经存在,因此将永远不会被调用.

Anyway I'm not sure why it was decided not to override, if there was such decision at all when designing the language. I think it would be an interesting feature and if there is a good reason not to implement it at least it should emit a warning saying that since the method already exists it will never be called.

也许我会为F#编译器打开一个问题或建议.

Maybe I will open an issue or a suggestion for the F# compiler.

这篇关于使用扩展方法覆盖F#中的静态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆