Проверка значения по умолчанию с помощью универсальных типов [дубликат]

Этот вопрос уже имеет ответ здесь:

Я хочу быть в состоянии проверить, является ли значение значением по умолчанию для своего типа значения. Идеально, я хотел бы сказать:

DoSomething(TValue value) {
    if (value == default(TValue)) {
        ...
    }
}

Однако компилятор жалуется, что не может сделать a == сравнение на TValue и TValue. Это - лучшее обходное решение, которое я придумал до сих пор:

DoSomething(TValue value) {
    if (value == null || value.Equals(default(TValue))) {
        ...
    }
}

Существует ли более изящный/корректный способ пойти об этом?

9
задан StriplingWarrior 2 February 2010 в 20:32
поделиться

4 ответа

public bool EqualsDefaultValue<T>(T value)
{
    return EqualityComparer<T>.Default.Equals(value, default(T));
}
39
ответ дан 4 December 2019 в 06:08
поделиться

Добавьте ограничение класса, и он должен работать.

public void Test<T>(T instance) where T : class
{
    if (instance == default(T))
    {

    }
}

Или если вы хотите только типы ценностей, вы можете сделать это.

public void Test<T>(T instance) where T : struct, IEquatable<T>
{
    if (instance.Equals(default(T)))
    {

    }
}
4
ответ дан 4 December 2019 в 06:08
поделиться

Добавление к ответам, размещенным здесь, я думаю, что мы также должны указывать, если вы хотите ценить или справочное равенство:

static public class MyGenericHelper
{
    static public bool EqualsByValue<T>(T x, T y)
    {
        return EqualityComparer<T>.Default.Equals(x, y);
    }

    static public bool EqualsByReference<T>(T x, T y)
    {
        if (x is ValueType) return EqualityComparer<T>.Default.Equals(x, y) // avoids boxing

        return Object.ReferenceEquals(x, y);
    }
}

мы все просто любим создавать и поддерживать маленький помощник Цилльона такие методы, не так ли: ->

1
ответ дан 4 December 2019 в 06:08
поделиться

Ваша проблема заключается в том, что тип Genric (без ограничения) должен быть «коммутацией» для любого типа. Поскольку не все типы имеют an == Оператор Ваш код не скомпилируется.

Один из способов решить это, чтобы добавить ограничение класса, однако, поскольку ваше используемое значение по умолчанию (TVALUE), которое бы предположить, что код для работы с другими типами. (В противном случае просто используйте NULL вместо по умолчанию (TVALUE). Одно решение может быть чем-то похожем на то, что Bryan Watts предлагает

bool DoSomething<TValue>(TValue value) {
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue));
}

, или вы могли бы обернуть его в методе расширения

bool IsDefault<TValue>(this TValue value) {
    return EqualityComparer<TValue>.Default.Equals(value, default(TValue));
}
1
ответ дан 4 December 2019 в 06:08
поделиться
Другие вопросы по тегам:

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