C#:GenericType == 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
}
但后来我最终重复自己...我不喜欢。 问题如下:
thing == null;
这里 ReSharper 警告可能将值类型与“null”进行比较。
thing == default(T);
这里我得到编译器错误:无法将运算符“==”应用于类型“T”和“T”的操作数。
thing.Equals(null|default(T));
thing
显然可以为 null(这就是我必须检查的原因!),因此会导致 NullReferenceException。
null|default(T).Equals(thing);
null 和 default(T) 通常也为 null...
有没有一种干净的方法来做到这一点?
I need to check a generic object for null, or default(T). But I have a problem... Currently I have done it like this:
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
}
But then I end up repeating myself... which I don't like. The problem is the following:
thing == null;
Here ReSharper warns about Possible compare of value type with 'null'.
thing == default(T);
Here I get compiler error: Cannot apply operator '==' to operands of type 'T' and 'T'.
thing.Equals(null|default(T));
thing
can obviously be null (that's why I have to check!), so will cause NullReferenceException.
null|default(T).Equals(thing);
null and default(T) is very often null as well...
Is there a clean way to do this??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
正确的做法是:
不打拳击。 您甚至可以像这样定义一个扩展方法:
.. 并像这样调用它:
不过,我个人不关心 T 上的扩展方法(例如这个对象 IsNull()),因为它有时会妨碍可读性。
The proper way to do this is:
No boxing. You could even define an extension method like this:
.. and invoke it like this:
Though, I personally don't care for extension methods on T (e.g. this object IsNull()) since it hampers readability sometimes.
如果拳击不是问题,您可以使用:
If boxing isn't an issue, you could just use:
当我需要测试该值是否为 NULL 时,我使用下面的方法。 我通常在调用采用任何类型但不包括空值的方法(例如缓存)时使用此方法。
When I need to test if the value is NULL I use the method below. I typically use this when calling methods that take any type but not nulls such as the Cache.
打一点拳击就可以了。
A bit of boxing will do the job just fine.
我目前能想到的最好的事情是:
编辑:
显然,有一个我不知道的静态
object.Equals
方法:这更好。
Best thing I can think of at the moment is:
Edit:
Apparently, there's a static
object.Equals
method I was not aware of:This is better.
您可以通过注意可以静态确定类型的可为空性来完全避免装箱。
您可以执行以下操作:
isDefault
的私有静态只读变量,其类型为Predicate
v==null
或default(T).Equals(v)
isDefault(x )
而不是代码其余部分中的x==null
下面是一个示例:
You can avoid boxing altogether by noting that nullability of a type can be determined statically.
Here is what you can do:
isDefault
of typePredicate<T>
in your generic classv==null
ordefault(T).Equals(v)
depending on the outcomeisDefault(x)
instead ofx==null
in the rest of your codeHere is an example:
通过测试:
With Tests:
这有什么问题吗?
如果它是值类型,那么 JIT 将简单地完全删除该语句。
What is wrong with this?
If it is a value type then the JIT will simply remove the statement altogether.