Can't operator == be applied to generic types in C#?

前端 未结 12 651
囚心锁ツ
囚心锁ツ 2020-11-22 02:21

According to the documentation of the == operator in MSDN,

For predefined value types, the equality operator (==) returns true if th

相关标签:
12条回答
  • 2020-11-22 02:44

    There is an MSDN Connect entry for this here

    Alex Turner's reply starts with:

    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.

    0 讨论(0)
  • 2020-11-22 02:46
    
    bool Compare(T x, T y) where T : class { return x == y; }
    
    

    The above will work because == is taken care of in case of user-defined reference types.
    In case of value types, == can be overridden. In which case, "!=" should also be defined.

    I think that could be the reason, it disallows generic comparison using "==".

    0 讨论(0)
  • 2020-11-22 02:46

    The .Equals() works for me while TKey is a generic type.

    public virtual TOutputDto GetOne(TKey id)
    {
        var entity =
            _unitOfWork.BaseRepository
                .FindByCondition(x => 
                    !x.IsDelete && 
                    x.Id.Equals(id))
                .SingleOrDefault();
    
    
        // ...
    }
    
    0 讨论(0)
  • 2020-11-22 02:47

    Well in my case I wanted to unit-test the equality operator. I needed call the code under the equality operators without explicitly setting the generic type. Advises for EqualityComparer were not helpful as EqualityComparer called Equals method but not the equality operator.

    Here is how I've got this working with generic types by building a LINQ. It calls the right code for == and != operators:

    /// <summary>
    /// Gets the result of "a == b"
    /// </summary>
    public bool GetEqualityOperatorResult<T>(T a, T b)
    {
        // declare the parameters
        var paramA = Expression.Parameter(typeof(T), nameof(a));
        var paramB = Expression.Parameter(typeof(T), nameof(b));
        // get equality expression for the parameters
        var body = Expression.Equal(paramA, paramB);
        // compile it
        var invokeEqualityOperator = Expression.Lambda<Func<T, T, bool>>(body, paramA, paramB).Compile();
        // call it
        return invokeEqualityOperator(a, b);
    }
    
    /// <summary>
    /// Gets the result of "a =! b"
    /// </summary>
    public bool GetInequalityOperatorResult<T>(T a, T b)
    {
        // declare the parameters
        var paramA = Expression.Parameter(typeof(T), nameof(a));
        var paramB = Expression.Parameter(typeof(T), nameof(b));
        // get equality expression for the parameters
        var body = Expression.NotEqual(paramA, paramB);
        // compile it
        var invokeInequalityOperator = Expression.Lambda<Func<T, T, bool>>(body, paramA, paramB).Compile();
        // call it
        return invokeInequalityOperator(a, b);
    }
    
    0 讨论(0)
  • 2020-11-22 02:48

    In general, EqualityComparer<T>.Default.Equals should do the job with anything that implements IEquatable<T>, or that has a sensible Equals implementation.

    If, however, == and Equals are implemented differently for some reason, then my work on generic operators should be useful; it supports the operator versions of (among others):

    • Equal(T value1, T value2)
    • NotEqual(T value1, T value2)
    • GreaterThan(T value1, T value2)
    • LessThan(T value1, T value2)
    • GreaterThanOrEqual(T value1, T value2)
    • LessThanOrEqual(T value1, T value2)
    0 讨论(0)
  • 2020-11-22 02:49

    So many answers, and not a single one explains the WHY? (which Giovanni explicitly asked)...

    .NET generics do not act like C++ templates. In C++ templates, overload resolution occurs after the actual template parameters are known.

    In .NET generics (including C#), overload resolution occurs without knowing the actual generic parameters. The only information the compiler can use to choose the function to call comes from type constraints on the generic parameters.

    0 讨论(0)
提交回复
热议问题