我希望能够检查值是否是其值类型的默认值。理想情况下,我想说:
DoSomething<TValue>(TValue value) {
if (value == default(TValue)) {
...
}
}
然而,编译器抱怨它无法在TValue和TValue上进行==
比较。这是我到目前为止提出的最好的解决方法:
DoSomething<TValue>(TValue value) {
if (value == null || value.Equals(default(TValue))) {
...
}
}
有更优雅/正确的方法吗?
答案 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;