我有一个愚蠢的问题,我需要在 F# 类中实现具有以下方法的接口(interface):
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<'T when 'T : not struct> : unit -> a' when a': not struct 和 'a: null 没有正确的类型来覆盖相应的抽象方法。所需的签名是 'MyMethod<'T when 'T : not struct> : 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<'T when 'T : not struct> : unit -> 'T when 'T : not struct' 没有正确的类型来覆盖相应的抽象方法。
谢谢你的帮助。
最佳答案
而不是返回 null
(推断有某种类型 'a
,通过返回 null :?> 'T
进行检查)您可以使用
type public Implementation() =
interface IMyInterface with
member __.MyMethod<'T when 'T : not struct>() = Unchecked.defaultof<'T>
我更喜欢
__
超过 this
不使用时。TL;博士;
class
C# 中的约束隐式包含 null
.不幸的是,不允许在 F# 中指定:member __.MyMethod<'T when 'T : not struct and 'T : null>() = Unchecked.defaultof<'T>
结果是:
The member 'MyMethod<'T when 'T : not struct and 'T : null> : unit -> 'T when 'T : not struct and 'T : null' does not have the correct type to override the corresponding abstract method. The required signature is 'MyMethod<'T when 'T : not struct> : unit -> 'T when 'T : not struct'.
但是,使用这些跨语言的类和接口(interface)无论如何都需要特别注意,因为 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
关于interface - 具有类型约束的接口(interface)方法的 F# 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38357737/