Что мне делать в отношении "Возможное сравнение типа значения с" null "?
При написании этого метода для пользовательской NUnit Constraint.
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 предупреждает, что expected
и actual
могут быть ValueType
объектами.
e.g. TExpected is DateTime
expected == null;// but DateTime is a struct.
Каковы правила при сравнении значения ValueType с нулем и как я должен писать метод для учета этого, не ограничивая общие параметры, добавляя ограничение класса?
Ответы
Ответ 1
Не меняйте код - просто игнорируйте предупреждение. Если параметр типа является типом значения, отличным от NULL, сравнение всегда будет терпеть неудачу, и он всегда будет называть ToString()
. Я не знаю, действительно ли это произошло, но я не удивлюсь... и это не похоже на критически важный для работы код:)
Я лично оставил бы предупреждение "on", но проигнорировал его в этом конкретном случае - возможно, с комментарием.
Я думаю, что несколько раз сталкивался с тем же предупреждением, когда переопределял LINQ to Objects.
Ответ 2
Каковы правила при сравнении значения ValueType с нулем и как я должен писать метод для учета этого, не ограничивая общие параметры, добавляя ограничение класса?
Если вы не знаете, что они будут ссылочными типами, вы можете сказать
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";
}
}
Ответ 3
Я использую что-то вроде этого, чтобы проверить значение null на общих типах:
if (Equals(result, Default(T)))
Ответ 4
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
).