运算符使用泛型函数参数重载

时间:2014-08-13 16:42:45

标签: c# generics operator-overloading

我对泛型方法的运算符解析有问题。

根据我对函数EqualOperatorGeneric中规范7.3.4节的理解(下面的示例代码),应该找到类型A上的==运算符的正确重载,但它似乎得到(对象的候选者) ,对象)。

我做了一件非常明显错误的事吗?有没有一种方法可以获得预期的行为,如果没有,我可以将给定的情况转换为编译时或运行时错误吗?

public class A
{
    public A(int num)
    {
        this.Value = num;
    }

    public int Value { get; private set; }

    public override bool Equals(object obj)
    {
        var other = obj as A;
        if (Object.ReferenceEquals(other, null))
            return false;

        return Object.Equals(this.Value, other.Value);
    }

    public override int GetHashCode()
    {
        return this.Value.GetHashCode();
    }

    public static bool operator ==(A l, A r)
    {
        if (Object.ReferenceEquals(l, null))
        {
            return !Object.ReferenceEquals(r, null);
        }

        return l.Equals(r);
    }

    public static bool operator !=(A l, A r)
    {
        return !(l == r);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(EqualOperatorGeneric(new A(1), new A(1)));
    }

    public static bool EqualOperatorGeneric<L, R>(L l, R r)
        where L : class
        where R : class
    {
        return l == r;
    }
}

输出:

  

2 个答案:

答案 0 :(得分:2)

编译EqualOperatorGeneric时,==运算符需要在编译方法时静态绑定到单个实现。对于通用方法的每个单独使用,它不单独绑定。

这就是将泛型与C ++模板区分开来的原因。泛型方法编译一次,然后应用于每个类型参数集的每个用法,而模板则为每组泛型参数单独编译。

答案 1 :(得分:1)

在浏览规范之后,我意识到您可以使用dynamic关键字将运算符的绑定从编译时延迟到运行时。这解决了我一直遇到的问题:

public static bool EqualOperatorGeneric<L, R>(L l, R r)
{
    dynamic dl = l, dr = r;
    return dl == dr;
}