I have the following code:
class Foo<T> where T : struct
{
private T t;
[...]
public bool Equals(T t) { return this.t == t; }
}
When I try to compile, it gives me the following error:
Operator '==' cannot be applied to operands of type 'T' and 'T'
Why can't it be done? If the constraint was where T : class
it would have worked. But I need it to be value type because in my implementation this generic will always be an enum.
What I am doing to circunvent the situation is using Object.Equals()
method. Will it ensure the correct behavior all the time, since I am only comparing between T?
This is an unpopular limitation of the constraints system. You cannot constrain a value type according to specific operations on it unless they are defined in an interface. So you cannot constrain for operator definitions, as they will not be defined on all value types, and the struct
constraint allows any value type to be passed in.
struct A { }
That has no ==
defined, and yet your constraint says you'd be happy to accept it. So you cannot use ==
.
The reason its different for reference types is because there is always a definition of ==
available for them (identity comparison).
The implementation of ==
on enum
is close enough to the implementation of Equals
that your workaround is fine.
Compare with the situation for >
with numeric types! No such workaround there. The standard numbers have no interface with methods like GreaterThan
, etc.
Have a look at this article by Jon Skeet and Marc Gravell. It describes an implementation of "generic operators" using Linq expressions. The actual implementation is available in the MiscUtil library
精彩评论