【问题标题】:F# implementation of interface method with type constraint具有类型约束的接口方法的 F# 实现
【发布时间】:2016-11-16 09:34:27
【问题描述】:

我有一个愚蠢的问题,我需要在 F# 类中实现具有以下方法的接口:

public interface IMyInterface
{
    T MyMethod<T>() where T : class;
}

我在 F# 中苦苦挣扎。我尝试了不同的方法。但问题是必须返回 T 类型的对象。不接受空值:

type public Implementation() = 
    interface IMyInterface with
        member this.MyMethod<'T when 'T : not struct>() = null

错误:成员 'MyMethod : unit -> a' when a': not struct 和 'a: null 没有正确的类型来覆盖相应的抽象方法。所需的签名是 'MyMethod : unit -> 'T when 'T: not struct'

所以我尝试将 T 作为类的参数,但仍然没有我完成错误:

type public Implementation(data : 'T when 'T : not struct) = 
    interface IMyInterface with
        member this.MyMethod<'T when 'T : not struct>() = data

错误:成员 'MyMethod : unit -> 'T when 'T : not struct' 没有正确的类型来覆盖相应的抽象方法。 em>

感谢您的帮助。

【问题讨论】:

    标签: interface f# type-constraints


    【解决方案1】:

    您可以使用而不是返回null(推断有某种类型'a,通过返回null :?&gt; 'T进行检查)

    type public Implementation() = 
        interface IMyInterface with
            member __.MyMethod<'T when 'T : not struct>() = Unchecked.defaultof<'T>
    

    我更喜欢__ 而不是this 不使用时。

    TL;DR;

    C# 中的class 约束隐式包含null。不幸的是,不允许在 F# 中指定:

    member __.MyMethod<'T when 'T : not struct and 'T : null>() = Unchecked.defaultof<'T>
    

    结果:

    成员 'MyMethod : unit -> 'T when 'T: not struct and 'T: null' 没有正确的类型来覆盖对应抽象方法。所需的签名是 'MyMethod : unit -> 'T when 'T : not struct'。

    但是,使用这些跨语言的类和接口无论如何都需要特别注意,因为 C# 和 CLR 允许 null 值,而 F# 不允许。

    为了与 null 最佳重载 F# isNull 进行比较(请参阅此 answer):

    let inline isNull (x:^T when ^T : not struct) = obj.ReferenceEquals (x, null)
    

    除非你的类型允许null,否则你可以使用标准的isNull

    [<AllowNullLiteral>]
    type Foo() =
        member __.Bar() = ()
    
    (Implementation() :> IMyInterface).MyMethod<Foo>() |> isNull // true
    

    【讨论】:

    • 这个答案是正确的,但是根据你需要这个类的上下文,它可能不是你想要的。如果'T 是一个类,这个实现将返回null,如果它是一个F# 类,编译器不会(轻易地)让你将它与null 进行比较。所以请注意这一点。
    • @OverlordZurg 感谢您指出这一点。我添加了一个 TL;DR; :-)
    • this answer 中的代码对任何引用类型、F# 或其他类型执行空值检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多