Gab*_*iel 16 generics f# interface
在C#中,我可以使用两个不同的类型参数在一个类上实现两次泛型接口:
interface IFoo<T> { void Foo(T x); }
class Bar : IFoo<int>, IFoo<float>
{
public void Foo(int x) { }
public void Foo(float y) { }
}
Run Code Online (Sandbox Code Playgroud)
我想在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 = ()
Run Code Online (Sandbox Code Playgroud)
但它给出了编译器错误:
这种类型的实现或继承在不同类属实例相同的接口
'IFoo<float>'
和'IFoo<int>'
.在此版本的F#中不允许这样做.
Bri*_*ian 11
现在我不知道允许这个的计划..该功能已经计划好,至少部分(见注释)在F#4.0中实现.
我认为它目前不允许的唯一原因是它实现起来非常重要(特别是使用F#类型推断),并且在实践中很少出现(我只记得一位客户曾经问过这个问题).
鉴于无限的时间和资源,我认为这是允许的(我可以想象这将被添加到该语言的未来版本中),但是现在看起来这似乎不值得支持的功能.(如果您知道强烈的激励案例,请发送邮件至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"); }
}
Run Code Online (Sandbox Code Playgroud)
并从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"
Run Code Online (Sandbox Code Playgroud)
所以这就是F#这个"边界"的东西通常会发生的事情 - 即使你不能在语言中编写相同的东西,F#也可以使用这个东西.