运算符'=='不能应用于T型?
-
24-10-2019 - |
题
我认为这种方法有效,但我错了:
static void Equals<T>(T x, T y)
{
return x == y; //operator == can't be applied to type T
}
阅读指定后(v3.0中的第7.2.4节和第7.3.4节中的第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#中的所有内容都来自对象。在步骤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
方法。
解决方案
对您阅读规格有好处,但您停止阅读太早。如果您进一步阅读,您将会得到这一点:
预定义的参考类型平等操作员需要以下一个:
这两个操作数都是已知的参考类型或文字零的类型的值。此外,从任何操作数的类型到其他操作数的类型都存在明确的参考转换。
一个操作数是T型的值,其中T是类型参数,另一个操作数是字面的空。此外,t没有值类型约束。
除非这些条件之一是正确的,否则会发生绑定时间误差。 (*)
该错误不是来自过载分辨率的错误;错误是超载分辨率会选择预定义的参考类型等效操作员,并且您没有参考类型。
考虑您的代码。是什么阻止t是一个值类型,而没有相等性运算符?没有什么。假设我们回到了对象版本。这两个操作数都将盒子到不同的位置,因此即使具有相同的内容,也可以是参考线。由于那是缓慢的,令人困惑和错误的,因此即使尝试都是非法的。
您为什么首先要做这件事?如果您的方法起作用,那是不行的,那么您的方法将是 更差 首先简单地使用==。您打算用这种方法添加到世界的价值是多少?
(*)我已经将此句子中的语法错误报告给了规格维护者。
其他提示
如果知道 where T : class
, ,进行参考比较。操作员通常对仿制药几乎没有支持,但是有解决方法。 Miscutil提供 间接支持操作员 关于仿制药,否则 EqualityComparer<T>.Default.Equals(x,y)
是一个不错的选择。
我喜欢使用 EqualityComparer<T>.Default
为了这。
它是基于覆盖的 Equals
方法,但使用 IEquatable<T>
如果有的话,请避免实现价值类型的拳击。
EqualityComparer<T>.Default.Equals(x, y)
利用 .Equals()
方法,请确保 T
实施 IComparable