在不同的通用实例中实现相同的接口 [英] Implementing the same interface at different generic instantiations

查看:83
本文介绍了在不同的通用实例中实现相同的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我可以在一个类上使用两个不同的类型参数两次实现通用接口:

code> interface IFoo< T> {void Foo(T x); }

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆