【发布时间】:2011-08-14 01:31:39
【问题描述】:
我认为这个方法是有效的但我错了:
static void Equals<T>(T x, T y)
{
return x == y; //operator == can't be applied to type T
}
阅读规范后(v3.0 中的第 7.2.4 节和 v4.0 中的第 7.3.4 节):
7.2.4 二元运算符重载解析
x 形式的运算 op y,其中 op 是可重载的 二元运算符,x 是 类型 X,y 是类型的表达式 Y,处理如下:
候选用户定义运算符集 由 X 和 Y 提供用于操作 确定算子 op(x, y)。这 集合由 X 提供的候选运算符和 Y提供的候选运算符, 每个使用的规则确定 §7.2.5。如果 X 和 Y 是同一类型, 或者如果 X 和 Y 来自于 公共基础类型,然后共享 候选运算符仅出现在 合集一次。
如果集合 候选用户定义的运算符是 不为空,则这成为集合 的候选运营商 手术。否则,预定义的 二元运算符 op 实现, 包括他们的提升形式,成为 的候选运算符集 手术。预定义的 给定运算符的实现 在描述中指定 运算符(第 7.7 节到第 7.11 节)。
第 7.4.3 节的重载决策规则应用于候选运算符集,以选择关于参数列表 (x, y) 的最佳运算符,该运算符成为重载决策的结果过程。如果重载决策未能选择单个最佳运算符,则会发生编译时错误。
在第 2 步中,我认为应该应用这个预定义的实现:
bool operator ==(object x, object y);
bool operator !=(object x, object y);
因为 C# 中的所有内容都派生自 Object。步骤 3 中如何发生编译时错误?在这种情况下,我认为不可能出现“重载分辨率无法选择”。
编辑当我实施这样的事情时,我想到了这个问题:
class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
public bool Equals(TEnum x, TEnum y)
{
return x == y;
}
public int GetHashCode(TEnum obj)
{
return (int)obj;
}
}
恐怕我需要构建一个表达式并在Equals方法中动态调用它。
【问题讨论】:
-
FWIW,
(object)x == (object)y是有效的——但考虑(object)1 == (object)1作为不希望这样做的原因。只需要帮助T到非泛型。 -
讨论有点抽象,但 Eric Lippert 指出,所有内容派生都来自
Object是一种普遍的误解。 blogs.msdn.com/b/ericlippert/archive/2009/08/06/… 他提到的一个相关点是类型参数不是从任何东西派生的。 -
@pst:我认为
(dynamic)x == (dynamic)y是您想要的。否则它只是做一个引用相等。 -
我有点困惑;为什么在枚举上内置的平等实现还不够?也就是说,为什么不直接使用默认的相等比较器呢?
标签: c# .net operator-overloading language-specifications