2010-02-02 60 views
8

我希望能够检查某个值是否为其值类型的默认值。理想情况下,我想说:使用泛型类型进行缺省值检查

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

然而,编译器抱怨说,它不能对TValue和TValue一个==比较。这是我想出来的迄今为止最好的解决方法:

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

有没有去这更优雅/正确的方法?

回答

37
public bool EqualsDefaultValue<T>(T value) 
{ 
    return EqualityComparer<T>.Default.Equals(value, default(T)); 
} 
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))) 
    { 

    } 
} 
+4

如果你抛出''类'约束你可能只是检查'null' ... – 2010-02-02 20:48:49

+0

@Marc - 我知道,在这一点上它是一个问题的偏好。 – ChaosPandion 2010-02-02 20:51:48

+0

我希望能够为任何类型的工作,包括价值和类的类型。 – StriplingWarrior 2010-02-02 21:02:27

1

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

解决它的一种方法是添加类约束,但是因为使用默认(TValue)会暗示您希望代码与其他类型一起使用。 (否则只是使用空,而不是默认(TValue)。一种解决方案是类似于布赖恩·沃茨建议

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

添加到包起来的东西张贴在这里的答案,我想我们也应该能够指定是否我们想要的数值或引用平等:

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

我们都只是爱创造和维持一个小数不胜数的H ^像这样的方法我们不: - >

+0

在可读性和性能方面,似乎'typeof(T).IsValueType'优于'x是ValueType'。我错了吗? – StriplingWarrior 2010-02-02 22:23:10

+1

也许可读性有时候是一种味道的问题。 : - > ...''x对于我来说直觉上“感觉更快”是因为'typeof(T).IsValueType'必须检索相当重的'Type'实例,并且Reflector显示'.IsValueType'属性调用一个在'RuntimeType'中实现的虚拟方法,最终调用extern。但是,我是谁来判断,我不是内部人士。他们甚至可能会按照相同的说明进行编译。也许这是一个很好的新问题。 ;-) ...或者你可以自己做一些性能测试,如果它是至关重要的。 – herzmeister 2010-02-02 23:18:41

+0

这并不重要,但我很好奇,所以我做了一个快速测试,你是对的! 'x是ValueType'大约需要三分之一的时间。 – StriplingWarrior 2010-02-03 17:29:08