0
    public static IEnumerable<T> Method<T>(IEnumerable<T> iterable){

    T previous = default(T);
    foreach(T current in iterable){

        if (!current.Equals(previous)){

            previous = current;
            yield return current;
        }
    }
}

我对此代码没有任何疑问,但如果可以使用以下方法比较两个类型 T 的对象,我只是为什么:

if (!current.Equals(previous))

那么为什么无法使用以下方法进行比较:

if (!current == previous)

这 !给你一个错误说

操作员 '!' 不能应用于“T”类型的操作数

如果你删除它,你会得到:

运算符“==”不能应用于“T”和“T”类型的操作数

我放弃了代码挑战,因为它似乎在告诉我你真的无法将一个 T 与另一个进行比较。然后我发现你可以做到这一点,但只是使用不同的语法/使用特定的方法。

谁能告诉我为什么会这样?

4

3 回答 3

2

.Equals是 的一部分System.Object。现在没有办法限制泛型支持特定的运算符重载。但是,您可以使用IEquatable<T>orIEqualityComparer<T>来确保该类型实现其相等定义。

于 2022-01-15T14:57:00.523 回答
1

请参阅指定语言规范的这一部分==。您可以看到该语言仅具有这些==预定义重载:

bool operator ==(int x, int y);
bool operator ==(uint x, uint y);
bool operator ==(long x, long y);
bool operator ==(ulong x, ulong y);
bool operator ==(float x, float y);
bool operator ==(double x, double y);
bool operator ==(decimal x, decimal y);
bool operator ==(bool x, bool y);
bool operator ==(E x, E y); // for every enum E
bool operator ==(C x, C y); // for every class C
bool operator ==(string x, string y);
bool operator ==(System.Delegate x, System.Delegate y);

你的方法中的类型参数T不受任何约束,那么如果它是一个结构类型呢?从上面的列表中可以看出,没有==为任意结构类型定义运算符。

如果你添加一个T: class约束,那么你就可以使用==它,因为==所有类都有一个运算符。

另一方面,在 中Equals声明了一个方法System.Object,C# 中的每个类型都从该方法继承。因此,可以使用Equalstype 的值T,即使T可以是任何类型。

于 2022-01-15T19:11:50.320 回答
0

Please note that == can only mean value equality if the object is a primitive value type, a string, or a user struct with the operator == defined.

In all other cases, == is either not defined (value types) or refers to object.ReferenceEquals() that checks if both variables refer to the same object in memory.

Note that the new record types support the == operator with value semantics even though they are reference types. This is because behind the scenes they implement IEquatable<T> and define operator == to use .Equals().

于 2022-01-16T04:27:10.680 回答