C#: Альтернатива GenericType == пустой указатель

Я удалил проект и создал его снова. Он работал для меня. Спасибо всем за помощь

22
задан Svish 18 December 2009 в 12:16
поделиться

7 ответов

Если упаковка не является проблемой, Вы могли бы просто использовать:

object.Equals(value, default(T))
26
ответ дан 29 November 2019 в 03:23
поделиться

Немного упаковки сделает задание очень хорошо.

    static bool IsNullOrDefault<T>(T value)
    {
        return ((object)default(T)) == null ?
            ((object)value) == null :
            default(T).Equals(value);
    }
2
ответ дан 29 November 2019 в 03:23
поделиться

Лучшая вещь, о которой я могу думать в данный момент:

return value == null || value.Equals(default(T));

Редактирование:

, По-видимому, существуют помехи object.Equals метод, о котором я не знал:

return object.Equals(value, default(T));

Это лучше.

2
ответ дан 29 November 2019 в 03:23
поделиться

С Тестами:

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)); }
}
0
ответ дан 29 November 2019 в 03:23
поделиться

Правильный способ сделать это:

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 ()), поскольку он иногда затрудняет читаемость .

54
ответ дан 29 November 2019 в 03:23
поделиться

Вы можете полностью избежать бокса, отметив, что допустимость значения NULL для типа может быть определена статически.

Вот что вы можете сделать:

  1. Объявите частную статическую переменную только для чтения с именем isDefault типа Predicate в вашем универсальном классе
  2. Добавьте статический инициализатор в ваш универсальный класс, где вы проверяете допустимость значения T для T, и установите isDefault на v == null или ] по умолчанию (T). Равно (v) в зависимости от результата
  3. Используйте 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);
    }

}
1
ответ дан 29 November 2019 в 03:23
поделиться

Что с этим не так?

if (thing == default(T)) { }

Если это тип значения, то JIT просто удалит оператор полностью.

-1
ответ дан 29 November 2019 в 03:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: