运算符'=='不能被应用于类型T?应用于、运算符、类型

2023-09-02 10:52:03 作者:倾尽所洧呮为你

我觉得这种方法是有效的,但我错了:

I thought this method was valid but I was wrong:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}

阅读specifiation(在V4.0第7.2.4节在3.0和§7.3.4)后:

After reading the specifiation (§7.2.4 in v3.0 and §7.3.4 in v4.0):

7.2.4二元运算符重载解析

7.2.4 Binary operator overload resolution

形式X的操作   OP y,其中op是可重载   二元运算符,x是一个前pression   键入x,y是类型的前pression   Y,进行如下处理:

An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows:

  

候选的用户定义运算符   为操作提供的X和Y   操作符op(X,Y)被确定。该   集包括工会   用X提供的候选运算符和   用Y提供的候选运营商,   使用规则确定每   §7.2.5。如果X和Y是相同的类型,   或者如果X和Y是从衍生   常见的基本类型,然后共享   候选运营商只发生在   合集中一次。

The set of candidate user-defined operators provided by X and Y for the operation operator op(x, y) is determined. The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of §7.2.5. If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once.

如果该套   候选的用户定义运算符是   不为空,则它就会成为集   候选操作的   操作。否则,predefined   二元operator op实现,   包括它们的提升形式,成为   一组候选操作的   操作。在predefined   给定运算符的实现   在说明中仅指定   操作(第7.7节通过§7.11)。

If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Otherwise, the predefined binary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. The predefined implementations of a given operator are specified in the description of the operator (§7.7 through §7.11).

的7.4.3节中的重载决策规则应用于候选运算符集相对于参数列表(X,Y)选择最佳的运营商,而这个操作符变为重载的结果处理。如果重载决策未能选出单个最佳运算符,则发生编译时错误。

The overload resolution rules of §7.4.3 are applied to the set of candidate operators to select the best operator with respect to the argument list (x, y), and this operator becomes the result of the overload resolution process. If overload resolution fails to select a single best operator, a compile-time error occurs.

在第2步,我认为这predefined实施应适用:

In step 2 I think this predefined implementation should be applied:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

因为一切都在C#中派生自对象。如何能在步骤3中发生编译时错误?我不认为这有可能是重载决策未能选择在这种情况下。

since everything in C# derives from Object. How can a compile-time error occurs in step 3? I don't think it's possible that "overload resolution fails to select" in this case.

修改的问题来到我的脑海,当我正在实施这样的:

EDIT The question came to my mind when I was implementing something like this:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
    public bool Equals(TEnum x, TEnum y)
    {
        return x == y;
    }
    public int GetHashCode(TEnum obj)
    {
        return (int)obj;
    }
}

我怕我需要建立一个EX pression和动态地调用它等于方法。

推荐答案

适合您阅读的规范,但你不读的太快了。假如你看过进一步你会得到该位:

Good for you for reading the spec, but you stopped reading too soon. Had you read further you would have gotten to this bit:

在predefined引用类型相等运算符要求执行下列操作之一:

在Excel中,运算符 表示什么

The predefined reference type equality operators require one of the following:   

两个操作数是已知的基准型或字面零点的类型的值。此外,显式引用转换存在从一个操作数的到另一个操作数的类型的类型。

Both operands are a value of a type known to be a reference-type or the literal null. Furthermore, an explicit reference conversion exists from the type of either operand to the type of the other operand.

一个操作数是类型T的值,其中T是一个类型参数,另一个操作数的字面空。此外T没有值类型约束。

One operand is a value of type T where T is a type-parameter and the other operand is the literal null. Furthermore T does not have the value type constraint.

除非这些条件之一为真,则发生绑定时错误。 (*)

Unless one of these conditions are true, a binding-time error occurs. (*)

该错误是不是从重载决议;错误是重载会选择在predefined引用类型相等运算符,您不必引用类型。

The error isn't from overload resolution; the error is that overload resolution would have chosen the predefined reference type equality operator, and you don't have reference types.

考虑您的code。从什么是与上定义不等于运算符值类型停止T'什么也没有。假设我们回落到对象版本;这两个操作数的框到不同的位置,因此可以参考不平等的,即使他们有相同的内容。自认为是缓慢的,混乱和错误的,它是非法的,甚至尝试。

Consider your code. What stops T from being a value type with no equality operator defined on it? Nothing. Suppose we fell back to the object version; both operands would box to different locations and therefore be reference-unequal, even if they had the same content. Since that is slow, confusing and wrong, it is illegal to even try.

你为什么要做这件事情摆在首位?如果你的方法有效,它没有,那么你的方法是的糟糕的比单纯使用==摆在首位。什么是你打算加入到世界这种方法的价值呢?

Why are you trying to do this thing in the first place? If your method worked, which it doesn't, then your method would be worse than simply using == in the first place. What is the value you intend to add to the world with this method?

(*)我已经报告了这句话的语法错误规范的维护者。

(*) I've reported the grammatical error in this sentence to the spec maintainers.