在不同的通用实例中实现相同的接口 [英] Implementing the same interface at different generic instantiations
问题描述
class Bar:IFoo< int>,IFoo< float>
{
public void Foo(int x){}
public void Foo(float y){}
}
我想在F#中做同样的事情:
键入IFoo< a> =抽象成员Foo:'a - >单元
类型Bar()=
接口IFoo< int>与
[< OverloadID(int)>]
member this.Foo x =()
interface IFoo< float>与
[< OverloadID(float)>]
成员this.Foo x =()
但它给出了一个编译器错误:
这个类型在不同的泛型实例化处实现或继承相同的接口
'IFoo< float>'
和'IFoo< int>'
。这是不允许在这个版本的F#。
我找不到任何讨论这个问题在网络上。这种用法因为某种原因而皱眉吗?是否有计划在即将发布的F#版本中允许这样做?
解决方案 现在我不知道计划允许这个。。该功能已经计划好了,并且至少部分是在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); }
}
并从F#引用它(注释表明结果)
let cig = new CIG()
let idunno = cig:> IG< _> //输入IG< int> ;,猜测只是选择'第一个'接口?
让ii = cig:> IG< INT> //作品
ii.F(42)//打印int
let is = cig:> IG<串GT; //作品
is.F(foo)//打印str
所以这就是通常发生在这个'边界'的东西上,F# - F#可以消耗这些东西,即使你不能在语言中编写相同的东西。
In C#, I can implement a generic interface twice on one class, using two different type-parameters:
interface IFoo<T> { void Foo(T x); }
class Bar : IFoo<int>, IFoo<float>
{
public void Foo(int x) { }
public void Foo(float y) { }
}
I would like to do the same thing in 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 = ()
But it gives a compiler error:
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#.
I can't find any discussion of this issue on the web. Is such use frowned upon for some reason? Are there plans to allow this in an upcoming release of F#?
Right now I don't know of plans to allow this.. The feature has been planned and is, at least partially (see comments) implemented in F# 4.0.
I think the only reasons its currently disallowed are that it's non-trivial to implement (especially with F# type inference), and it rarely arises in practice (I only recall one customer ever asking about this).
Given an infinite amount of time and resources, I think this would be allowed (I can imagine this being added to a future version of the language), but right now it does not seem like this is a feature worth the effort of supporting. (If you know a strong motivating case, please mail fsbugs@microsoft.com.)
EDIT
As an experiment for the curious, I wrote this 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"); }
}
and referenced it from F# (with comments suggesting the results)
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"
so this is what typically happens on this 'boundary' stuff with F# - F# can consume this stuff ok, even if you can't author the same stuff from within the language.
这篇关于在不同的通用实例中实现相同的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!