Home Dashboard Directory Help
Search

Operator '==' cannot be applied to operands of type 'T' and 'T' by Malobukv


Status: 

Resolved
 as By Design Help for as By Design


4
0
Sign in
to vote
Type: Bug
ID: 304501
Opened: 10/13/2007 12:46:05 PM
Access Restriction: Public
0
Workaround(s)
view
2
User(s) can reproduce this bug

Description

Beginner C# developers who are accustomed to the following:
public class Test
{
    public int Value
    {
        get { return _Value; }
        set
        {
            if (_Value == value)
                return;

            _Value = value;
        }
    }
    private int _Value;
}

become disappointed why they could not use "if(_Value == value) {...}" for generics.
Details
Sign in to post a comment.
Posted by Qwertie on 7/7/2011 at 9:54 AM
"this behavior is by design and there is not an easy solution to enable use of with type parameters that may contain value types." Actually Microsoft is wrong. There is an easy solution: MS should extend the ceq opcode to function on value types as a bitwise operator. Then they could provide access to it in all .NET languages through a method that simply uses this opcode, e.g. "object.BitwiseOrReferenceEquals<T>(value, default(T))" that simply uses ceq on the arguments. For both value and reference types this would check for bitwise equality of the values (i.e. the two bit patterns on the evaluation stack). Of course, existing special behavior for "float" and "double" should be preserved, but for all other data types (including structures that contain floating-point numbers), a bitwise comparison should be employed.

This feature would not be hard to implement, and it would improve the performance of the LINQ-like features I added to a family of functional data structures I made in C# called VList/WList. Right now, figuring out if an arbitrary value type has changed or not is very slow.
Posted by Microsoft on 11/4/2007 at 3:41 PM
Thanks for reporting this issue you've encountered with Visual Studio 2008!

Unfortunately, this behavior is by design and there is not an easy solution to enable use of == with type parameters that may contain value types.

If the types are known to be reference types, the default overload of == defined on object tests variables for reference equality, although a type may specify its own custom overload. The compiler determines which overload to use based on the static type of the variable (the determination is not polymorphic). Therefore, if you change your example to constrain the generic type parameter T to a non-sealed reference type (such as Exception), the compiler can determine the specific == overload to use and the following code would compile:

public class Test<T> where T : Exception

If the types are known to be value types, == performs specific value equality tests based on the exact types used. There is no good "default" comparison here since reference comparisons are not meaningful on value types and the compiler cannot know which specific value comparison to emit. The compiler could emit a call to ValueType.Equals(Object) but this method uses reflection and is quite inefficient compared to the specific value comparisons. Therefore, even if you were to specify a value-type constraint on T, there is nothing reasonable for the compiler to generate here:

public class Test<T> where T : struct

In the case you presented, where the compiler does not even know whether T is a value or reference type, there is similarly nothing to generate that would be valid for all possible types. A reference comparison would not be valid for value types and some sort of value comparison would be unexpected for reference types that do not overload ==.

Alex Turner
Program Manager
Visual C#
Posted by Microsoft on 10/14/2007 at 5:59 PM
Thank you for your feedback. We are currently investigating. The investigation process normally takes 7-14 days. If this issue is urgent, please contact support directly (see http://support.microsoft.com).

If at any time your issue is closed unsatisfactorily, you may edit your issue via Connect and change the status to “Active.”

Thank you,
Visual Studio Product Team
Sign in to post a workaround.