日期:2014-05-17  浏览次数:20799 次

关于泛型方法重载的问题?盼各位高手解答一下!
在一个class里有两个重载方法,如下图所示:
public void InsertPosition(T x,T y)
{
    ///Method1
}

public void InsertPosition(T x,int y)
{
    ///Method2
}

1.首先编译没有问题。
2.当泛型类型T指定为int型之外的类型时,也完全没有问题。
3.当泛型类型T指定为int型时,会发生什么情况呢?重载消失了,两个方法的形式完全一样,如果两个形式完全一样的方法存在同一个类里,在编译时是通不过的。但是利用泛型时,编译通过了。但是运行时,却不会报错了。只是经过测试,一直是执行第二个方法。
有谁能帮忙解答一下为什么?

------解决方案--------------------
引用:
引用:
没有什么为什啊。当用int来代替,执行哪一个方法都是对的。

不可能,肯定有为什么?现在不是执行哪一个对错的问题,而是第一个方法是不会被执行的,你没有办法执行到它。
函数重载的话,总是执行最匹配的方法。第二个方法的参数中,第二个指明是 int 了,直接会调用第二个。忽略掉第一个.
------解决方案--------------------
引用:
引用:
引用 C#语言规范7.4.3.5 的论述:

7.4.3.5 泛型类中的重载
虽然声明的签名必须唯一,但是在替换类型实参时可能会导致出现完全相同的签名。在此类情形中,上述重载决策的附加规则将挑选最明确的成员。
下面的示例根据此规则演示有效和无效的重载:
interface I1<T> {...}
interface I2<T> {...}……

这个例子正好说明了“将挑选最明确的成员”这一规则:

        static void TestOverload<T>(C1<T> test, T value)
        {
            test.Test(value);
        }

由于Test方法有重载,所以它调用的应该是与value的类型最明确的重载
这时候value的类型是T,所以它会调用Test(T)这个方法。
你肯定会说,在Main方法里你调用TestOverload方法的时候已经明确value的类型了,因此这里应该匹配int类型。但事实上不是这样的,在编译的时候TestOverload方法是不知道谁会调用它的,也就不知道传入的value到底是什么类型,它只知道是个T类型,而且它要调用test的Test方法,但Test有重载,该调用哪个?既然value是T类型的,当然就是调用Test(T)了。
为了证明这一点,可以在加一个TestOverload方法的重载:

        static void Main(string[] args)
        {
            C1<int> c = new C1<int>();
            C1<string> c2 = new C1<string>();
            TestOverload(c, 3);        ///执行结果:Non-generic 而不是Test Generic Test