使用泛型类型检查默认值

时间:2010-02-02 20:32:53

标签: c# generics

我希望能够检查值是否是其值类型的默认值。理想情况下,我想说:

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

然而,编译器抱怨它无法在TValue和TValue上进行==比较。这是我到目前为止提出的最好的解决方法:

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

有更优雅/正确的方法吗?

4 个答案:

答案 0 :(得分:39)

public bool EqualsDefaultValue<T>(T value)
{
    return EqualityComparer<T>.Default.Equals(value, default(T));
}

答案 1 :(得分:4)

抛出类约束,它应该可以工作。

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)))
    {

    }
}

答案 2 :(得分:1)

你的问题是genric类型(没有约束)必须为任何类型“可编译”。由于并非所有类型都有一个==运算符,因此您的代码将无法编译。

解决此问题的一种方法是添加类约束,但是因为您使用默认(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));
}

答案 3 :(得分:1)

添加到此处发布的答案,我认为我们还应该能够指定您是否需要值或引用相等:

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

我们都喜欢创造和维护像我们这样的无数小帮手方法: - &gt;