What should I do about “Possible compare of value type with 'null'”?

前端 未结 4 1231
自闭症患者
自闭症患者 2021-02-04 23:06

While writing this method for a custom NUnit Constraint.

    private void AddMatchFailure(string failureName, TExpected expected, TActu         


        
相关标签:
4条回答
  • 2021-02-04 23:31

    What are the rules when comparing a ValueType to null and how should I write the method to account for that without limiting the generic parameters by adding a class constraint?

    If you do not know that they will be reference types, then you can say

    private void AddMatchFailure<TExpected, TActual>(
        string failureName,
        TExpected expected,
        TActual actual
    ) {
        _matchFailures.Add(
            String.Format(MatchFailureFormat, failureName,
            IsDefault<TExpected>(expected) ? DefaultStringForType<TExpected>() : expected.ToString(),
            IsDefault<TActual>(actual) ? DefaultStringForType<TActual>() : actual.ToString()
        );
    }
    
    private bool IsDefault<T>(T value) {
        if(typeof(T).IsValueType) {
            return default(T).Equals(value);
        }
        else {
            return Object.Equals(null, value);
        }
    }
    
    private string DefaultStringForType<T>() {
        if(typeof(T).IsValueType) {
            return default(T).ToString();
        }
        else {
            return "null";
        }
    }
    
    0 讨论(0)
  • 2021-02-04 23:47

    Don't change the code - just ignore the warning. If the type parameter is a non-nullable value type, the comparison will always fail and it'll always call ToString() instead. I don't know whether it's actually JITted away, but I wouldn't be surprised... and this doesn't sound like it's performance-critical code anyway :)

    I'd personally leave the warning "on", but ignore it in this particular case - possibly with a comment.

    I think I came across the same warning a few times when reimplementing LINQ to Objects.

    0 讨论(0)
  • 2021-02-04 23:48

    I'm using something like this to check for null on generic types:

    if (Equals(result, Default(T)))
    
    0 讨论(0)
  • 2021-02-04 23:50
    private void AddMatchFailure<TExpected, TActual>(string failureName, TExpected expected, TActual actual)
    {
        _matchFailures.Add(
            String.Format(MatchFailureFormat, failureName,
            (expected == default(TExpected)) ? "null" : expected.ToString(),
            (actual == default(TActual)) ? "null" : actual.ToString()));
    }
    

    Should do it.

    default(T) gives the default value for that type, for reference types that's null - for others it depends. (Enums it's the equivalent of (enumType)0 for example).

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