简体   繁体   中英

Comparing generic Nullable types

Imagine I have a generic method involving type T. In terms of usage, T will only ever be of type Nullable<long> or Nullable<Guid> .

Because T is Nullable, I can't impose the type constraint where T : IComparable<T> on the method.

Given this, what is the most performant way of determining equality between two variables of type T within the method?

I am currently passing in a lambda function like (x, y) => x == y .. but feel there must be a better way.

If T is always a Nullable, you can pass the underlying type's parameter (instead of Nullable<T> ), and then use Nullable.Compare to do the comparison:

public static void Method<T>(Nullable<T> n1, Nullable<T> n2)
    where T : struct
{
    int comparisonResult = Nullable.Compare(n1, n2);
    ...
}

The Comparer<T>.Default should handle perfectly well nullable values. It does a check about Nullable<> here so it should handle it.

Note that IComparable<> is used if you want to know <, >, <=, >=, == (so the order between two elements). If you only want Equals then use IEquatable<> (and EqualityComparer<T>.Default ).

Another way to implement - https://dotnetfiddle.net/EBjU54

Here: I created a proper nullable comparing logic in a separate class to check the equality of two nullable. Next, as the anwser of vc74, you pass the underlying type's parameter and use the NullableComparer to check.

public static bool Comparexxx<T>(this T? myValue, T? otherValue)
            where T : struct
            { 
                var comparer = new NullableComparer<T>();

                return comparer.Compare(myValue, otherValue) == 1;              
            } 

            public class NullableComparer<T> : IComparer<Nullable<T>>
                  where T : struct
            {

                 public int Compare(Nullable<T> x, Nullable<T> y)
                 {              
                    //Two nulls are equal
                    if (!x.HasValue && !y.HasValue)
                        return 1;

                    //Any object is greater than null
                    if (x.HasValue && !y.HasValue) 
                        return 0;

                    if (y.HasValue && !x.HasValue)
                        return 0;

                    //Otherwise compare the two values
                    return x.Value.Equals(y.Value) ? 1 : 0 ;
                 }

            }
    }

And calling

long? a = 10;           
long? b = 10;
var rs = a.Comparexxx<long>(b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM