在 C# 中,我可以使用两个不同的类型参数在一个类上实现两次泛型接口(interface):
interface IFoo<T> { void Foo(T x); }
class Bar : IFoo<int>, IFoo<float>
{
public void Foo(int x) { }
public void Foo(float y) { }
}
我想在 F# 中做同样的事情:
type IFoo<'a> = abstract member Foo : 'a -> unit
type Bar() =
interface IFoo<int> with
[<OverloadID("int")>]
member this.Foo x = ()
interface IFoo<float> with
[<OverloadID("float")>]
member this.Foo x = ()
但它给出了编译器错误:
This type implements or inherits the same interface at different generic instantiations
'IFoo<float>'
and'IFoo<int>'
. This is not permitted in this version of F#.
我找不到任何 discussion of this issue在网上。出于某种原因,这种用途是否令人不悦?是否有计划在即将发布的 F# 中允许这样做?
最佳答案
现在我不知道允许这个的计划.. 功能 has been planned并且至少部分(参见评论)在 F# 4.0 中实现。
我认为它目前不被允许的唯一原因是它的实现并不简单(尤其是 F# 类型推断),而且它在实践中很少出现(我只记得一个客户曾经问过这个问题)。
考虑到无限量的时间和资源,我认为这是允许的(我可以想象这将被添加到该语言的 future 版本中),但现在看来,这似乎不是一个值得努力支持的功能。 (如果您知道一个强有力的激励案例,请发送邮件至 fsbugs@microsoft.com。)
编辑
作为好奇的实验,我写了这个 C#:
public interface IG<T>
{
void F(T x);
}
public class CIG : IG<int>, IG<string>
{
public void F(int x) { Console.WriteLine("int"); }
public void F(string x) { Console.WriteLine("str"); }
}
并从 F# 中引用它(带有建议结果的评论)
let cig = new CIG()
let idunno = cig :> IG<_> // type IG<int>, guess just picks 'first' interface?
let ii = cig :> IG<int> // works
ii.F(42) // prints "int"
let is = cig :> IG<string> // works
is.F("foo") // prints "str"
所以这就是使用 F# 在这个“边界”东西上通常发生的事情 - F# 可以正常使用这些东西,即使你不能从该语言中创作相同的东西。
关于f# - 在不同的泛型实例中实现相同的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1464109/