Я удалил проект и создал его снова. Он работал для меня. Спасибо всем за помощь
Если упаковка не является проблемой, Вы могли бы просто использовать:
object.Equals(value, default(T))
Немного упаковки сделает задание очень хорошо.
static bool IsNullOrDefault<T>(T value)
{
return ((object)default(T)) == null ?
((object)value) == null :
default(T).Equals(value);
}
Лучшая вещь, о которой я могу думать в данный момент:
return value == null || value.Equals(default(T));
Редактирование:
, По-видимому, существуют помехи object.Equals
метод, о котором я не знал:
return object.Equals(value, default(T));
Это лучше.
С Тестами:
public class DefaultOrNullChecker<T> {
public bool Check(object x) {
return object.ReferenceEquals(x, null) || x.Equals(default(T));
}
}
[TestFixture]
public class Tests {
[Test] public void when_T_is_reference_type() {
Assert.IsFalse(new DefaultOrNullChecker<Exception>().Check(new Exception()));}
[Test] public void when_T_is_value_type() {
Assert.IsFalse(new DefaultOrNullChecker<int>().Check(123)); }
[Test] public void when_T_is_null() {
Assert.IsTrue(new DefaultOrNullChecker<Exception>().Check(null));}
[Test] public void when_T_is_default_value() {
Assert.IsTrue(new DefaultOrNullChecker<int>().Check(0)); }
}
Правильный способ сделать это:
return EqualityComparer<T>.Default.Equals(value, default(T))
Никакого бокса. Вы даже можете определить метод расширения, подобный этому:
public static void bool IsDefault<T>(this T value)
{
return EqualityComparer<T>.Default.Equals(value, default(T));
}
.. и вызывать его так:
return entry.IsDefault();
Хотя мне лично не нужны методы расширения на T (например, этот объект IsNull ()), поскольку он иногда затрудняет читаемость .
Вы можете полностью избежать бокса, отметив, что допустимость значения NULL для типа может быть определена статически.
Вот что вы можете сделать:
isDefault
типа Predicate
в вашем универсальном классе v == null
или ] по умолчанию (T). Равно (v)
в зависимости от результата isDefault (x)
вместо x == null
в остальной части кода Вот пример :
public class Example<T> {
private static readonly Predicate<T> isDefault;
static Example() {
// Nullability check is a bit ugly, but we do it once per T,
// so what the heck...
if (typeof(T).IsValueType &&
(!typeof(T).IsGenericType
|| typeof(T).GetGenericTypeDefinition() != typeof(Nullable<>)
)) {
// This is safe because T is not null
isDefault = val => default(T).Equals(val);
} else {
// T is not a value type, so its default is null
isDefault = val => val == null;
}
}
public bool Check(T value) {
// Now our null-checking is both good-looking and efficient
return isDefault(value);
}
}
Что с этим не так?
if (thing == default(T)) { }
Если это тип значения, то JIT просто удалит оператор полностью.