消除两个同样具体,相同的签名(通用方法)

时间:2015-09-02 16:56:29

标签: c# .net generics overloading overload-resolution

考虑以下课程:

public class TwoWayMap<T1, T2>
{
    public T2 Get(T1 x)
    {
        throw new System.NotImplementedException();
    }

    public T1 Get(T2 x)
    {
        throw new System.NotImplementedException();
    }
}

如果T1和T2是不同类型,我们调用Get,那么编译器就知道我们指的是哪一个。

var map1 = new TwoWayMap<int, string>();
map1.Get("hello");
map1.Get(5);

但是,如果类型相同,则两种方法共享相同的签名。就重载分辨率而言,它们具有同等的特异性(比如a generic vs a non-generic parameter)。因此,我们无法明确地调用该方法。

var map2 = new TwoWayMap<int, int>();
map2.Get(5);
  

编译器错误CS0121:以下操作之间的调用不明确   方法或属性:&#39; TwoWayMap.Get(T1)&#39;和&#39; TwoWayMap.Get(T2)&#39;

当然,我们可以(也应该)通过不使用相同的类型或提供专用的Get1Get2方法来避免此问题,但我想知道:在C#中是否存在某种方式。 NET消除歧义吗?是否可以致电map2.Get()

2 个答案:

答案 0 :(得分:1)

如果我更新了该API以使用GetSourceGetTarget我不知道Get(5)会是哪一个,编译器应该如何知道?

虽然仔细观察这个问题,但我认为你可以使用GetMethods()并只调用返回的第二个。

答案 1 :(得分:0)

你可以做这样的事情

interface IGetter1<T1,T2>
{
    T2 Get(T1 x);
}

interface IGetter2<T1, T2>
{
    T2 Get(T1 x);
}
public class TwoWayMap<T1, T2> : IGetter1<T1,T2>,IGetter2<T2,T1>
{
    public T2 Get(T1 x)
    {
        throw new System.NotImplementedException();
    }

    public T1 Get(T2 x)
    {
        throw new System.NotImplementedException();
    }
}

var map1 = new TwoWayMap<int, int>();
        var map2 =(IGetter1<int,int>) map1;
        var map3 = (IGetter2<int, int>) map1;
     //   map2.Get(5);
        map3.Get(5);