我应该怎么做“可能比较值类型与'null'”?

时间:2011-03-17 14:58:19

标签: c#

为自定义NUnit约束编写此方法时。

    private void AddMatchFailure<TExpected, TActual>(string failureName, TExpected expected, TActual actual)
    {
        _matchFailures.Add(
            String.Format(MatchFailureFormat, failureName,
            (expected == null) ? "null" : expected.ToString(),
            (actual == null) ? "null" : actual.ToString()));
    }

Resharper警告expectedactual可能是ValueType个对象。

e.g. TExpected is DateTime
   expected == null;//  but DateTime is a struct.

将ValueType与null进行比较时有哪些规则?如何在不限制通用参数的情况下通过添加类约束来编写方法来解决这个问题?

4 个答案:

答案 0 :(得分:79)

不要更改代码 - 只需忽略警告。如果type参数是非可空值类型,则比较将始终失败,并且它将始终调用ToString()。我不知道它是否真的被JIT打去了,但我不会感到惊讶......这听起来不像是性能关键代码:)

我个人将警告“打开”,但在这种特殊情况下忽略它 - 可能会发表评论。

我认为在重新实现LINQ to Objects时,我几次遇到同样的警告。

答案 1 :(得分:6)

  

将ValueType与null进行比较时有哪些规则?如何在不限制通用参数的情况下通过添加类约束来编写方法来解决这个问题?

如果您不知道它们是引用类型,那么您可以说

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";
    }
}

答案 2 :(得分:2)

我正在使用这样的东西来检查泛型类型的null:

if (Equals(result, Default(T)))

答案 3 :(得分:-3)

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()));
}

应该这样做。

default(T)给出了该类型的默认值,对于null的引用类型 - 对于它所依赖的其他引用类型。 (例如,枚举它相当于(enumType)0。)