具有重写方法的泛型类 - 被调用?

时间:2015-07-30 16:05:25

标签: c# generics override

我有一个类会覆盖加法运算符两次。一个采用type参数,一个采用double:

public class A<T>
{
    public A() { }

    public static A<T> operator +(A<T> a, T t)
    {
        Console.WriteLine("Generic add called.");
        return new A<T>();  // return to keep the compiler happy
    }

    public static A<T> operator +(A<T> a, double d)
    {
        Console.WriteLine("Double add called.");
        return new A<T>();  // return to keep the compiler happy
    }
}

当类由int类型参数化时,它的行为符合预期:

A<int> aInt = new A<int>();

var test = aInt + 3;
// -> Generic add called.

test = aInt + 3.0;
// -> Double add called.

但是,当double类型参数化时,会调用非泛型添加:

A<double> aDouble = new A<double>();

var otherTest = aDouble + 3.0;
// -> Double add called.

假设这种行为是常态,我知道会调用哪种行为。非通用覆盖将是首选。那说......

在发生碰撞时,是否始终首选非通用方法?

上述所有代码均可在您的浏览器中运行,here

编辑:This question是相关的,但是它询问的是通用方法,而不是类。他给出了这段代码:

class A
{
    public static void MyMethod<T>(T myVal) { }
    public static void MyMethod(int myVal) { }
}

不适用于我的使用示例。区分a.MyMethod(3)a.MyMethod<int>(3)是显而易见的 - 一个是通用的,一个不是。

2 个答案:

答案 0 :(得分:0)

简单回答是的。编译器假设因为您手动处理了特定的类型参数,这意味着它有一些特殊的逻辑。这就是调用第二个运算符的原因。更进一步说,运算符只不过是接受某些参数的静态方法。对于你的情况,它是一个二元运算符,所以静态方法有两个参数。

答案 1 :(得分:0)

将选择更具体的方法,但这种结构是一个坏主意,因为它是技术上未指明的行为。

引用@EricLippert,将代码片段替换为我的问题:

  

但是[aDouble + 3.0]的情况要糟糕得多。 CLR规则使这种情况“实现定义的行为”,因此任何旧的事情都可能发生。从技术上讲,CLR可以拒绝验证构造类型[A<double>]的程序。或者它可能崩溃。事实上它既没有;在糟糕的情况下,它能做到最好。

     
    

是否有这种类型构造的例子导致真正的实现定义行为?

  
     

是。有关详细信息,请参阅这些文章:

     

http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx

     

http://blogs.msdn.com/b/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx

相关问题