C#:GenericType的替代== null

Svi*_*ish 22 c# generics null

我需要检查null的通用对象,或者默认(T).但我有一个问题......目前我这样做了:

if (typeof(T).IsValueType)
{
  if(default(T).Equals(thing))
    // Do something
  else
    // Do something else
}
else
{
  if(thing == null)
    // Do something
  else
    // Do something else
}
Run Code Online (Sandbox Code Playgroud)

但后来我最终重复自己......我不喜欢.问题如下:

thing == null;
Run Code Online (Sandbox Code Playgroud)

ReSharper在这里警告可能将值类型与'null'进行比较.

thing == default(T);
Run Code Online (Sandbox Code Playgroud)

这里我得到编译器错误:不能将运算符'=='应用于'T'和'T'类型的操作数.

thing.Equals(null|default(T));
Run Code Online (Sandbox Code Playgroud)

thing 显然可以为null(这就是我必须检查的原因!),因此会导致NullReferenceException.

null|default(T).Equals(thing);
Run Code Online (Sandbox Code Playgroud)

null和default(T)通常也是null ...

这有干净的方法吗?

Jas*_*son 54

正确的方法是:

return EqualityComparer<T>.Default.Equals(value, default(T))
Run Code Online (Sandbox Code Playgroud)

没拳击.您甚至可以定义这样的扩展方法:

public static void bool IsDefault<T>(this T value)
{
    return EqualityComparer<T>.Default.Equals(value, default(T));
}
Run Code Online (Sandbox Code Playgroud)

..并像这样调用它:

return entry.IsDefault();
Run Code Online (Sandbox Code Playgroud)

虽然,我个人并不关心T上的扩展方法(例如这个对象IsNull()),因为它有时会妨碍可读性.


Jef*_*tes 26

如果拳击不是问题,你可以使用:

object.Equals(value, default(T))
Run Code Online (Sandbox Code Playgroud)

  • 看看Jason的答案是不需要拳击的单线程. (4认同)
  • 如何努力检查,取决于你在哪里.谢谢杰夫,最有可能以这种方法结束=) (2认同)

Dam*_*ern 8

当我需要测试值是否为NULL时,我使用下面的方法.我通常在调用任何类型但不是空值的方法时使用它,例如Cache.

public static bool IsNull<T>(this T value)
{
    var type = typeof(T);

    return (type.IsClass || Nullable.GetUnderlyingType(type) != null) 
        && EqualityComparer<T>.Default.Equals(value, default(T));

}
Run Code Online (Sandbox Code Playgroud)