从C#调用F#对象上的接口方法

7

给定一个 F# 类型:

type Foo() =
    member this.Prop with get() = ()

    interface IDisposable with
        member this.Dispose() = ()

在C#中,我创建了对象,但无法调用Dispose()

var x = new Foo();
x.Dispose(); // compile error, x does not contain a definition of Dispose

然而,我可以写成:
((IDisposable)x).Dispose(); // works, but I don't like the cast

有没有办法在C#中避免强制转换?这是否与F#不自动允许您从F#中调用.Dispose()的方式有关,以处理Foo类型?

2个回答

16

F#中的接口实现默认为显式。因此,除非从转换为接口的类型中查看(某种形式的强制转换),否则方法是不可见的。

要解决这个问题,可以公开一个具有与接口版本相同签名的实例方法。然后将接口转发到实例函数。例如:

type Foo() =
    member this.Prop with get() = ()
    member this.Dispose() = ()

    interface IDisposable with
        member this.Dispose() = this.Dispose()

1
还有一个原因让我(以及其他人)不在F#中使用面向对象编程 :) - Ankur
2
我认为这不是不在F#中使用OOP的理由。在F#中使用OOP应该是基于项目复杂性和整体设计的设计决策。 - 7sharp9
2
这个决定背后有什么理由,还是因为要向后兼容OCaml?在我看来,当一个学生“是一个”人时,我会假设学生有一个年龄,我可以直接询问,而不必先转换为IPerson。你知道为什么要这样实现吗? - gjvdkamp

3

对于这个特定的界面,怎么样:

using (var x = new Foo()) {
    ...
}

通常我会这样做,但在这种情况下我有List<Foo>,所以必须使用finally {foreach (var x in foos){x.Dispose();}}。 - Neil Mitchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接