我对泛型方法的运算符解析有问题。
根据我对函数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;
}
}
输出:
假
答案 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;
}