对空,可能是一个值或引用类型比较通用的? [英] Comparing a generic against null that could be a value or reference type?

查看:142
本文介绍了对空,可能是一个值或引用类型比较通用的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 公共无效DoFoo< T>(T富)其中T:ISomeInterface< T> 
{
//可能的值类型与空进行比较。
如果(富== NULL)抛出新的ArgumentNullException(富);
}



我特意只检查对空,因为我不希望限制一个值类型从等于其默认(T)。我的代码编译和工作得很好,这种方式(ReSharper的抱怨,但不是CodeAnalysis)。虽然我纳闷:




  • 有没有更标准的方式来处理这种情况
  • $? b $ b
  • 有没有从这个arrising问题的任何机会?

  • 当我拨打电话,并通过中值类型的引擎盖下确实会发生什么?


解决方案

我特意只检查对,因为我不希望从等于其默认(T)




这是一个很好的洞察力,但不要担心,你已经涵盖在那里。这是不合法的使用来比较默认 A T(T)== 在首位;重载不会找到一个独特的最好 == 运营商。



当然,你可以做 .Equals 的比较,但然后运行如果接收器崩溃的风险为空,而这恰恰是你正试图避免的。




是否有处理这种情况更标准的方式吗?




没有。比较null是在这里做正确的事情。



由于C#规范第7.10.6表示: X == NULL 结构是允许即使牛逼可以代表一个值类型,结果被简单地定义为假时,T是值类型。




有没有从这个arrising问题的任何机会呢?




当然。仅仅因为代码编译并不意味着它有您想要的语义。编写一些测试。




引擎盖下确实会发生什么,当我拨打电话,并通过在值类型?




现在的问题是模糊的。让我重组你到两个问题:




什么是引擎盖下真正发生时,我就用一个类型参数的一般方法的调用是一个非空值类型?




抖动汇编了与建筑的第一次调用该方法。当抖动检测到空检查,将其与假取代它,因为它知道没有非空值类型将永远等于空。




引擎盖下确实会发生什么事时,我就泛型方法调用使用类型参数,它是引用类型,但是这是一个结构类型的参数?例如:




 接口的IFoo:ISomeInterface<的IFoo> {} 
结构SFoo:{IFoo的任何}
...
DoFooInternal<的IFoo>(新SFoo());

在这种情况下,抖动不能的Elid空支票和呼叫网站无法回避的拳击。该SFoo实例将盒装,以及盒装SFoo参考将被检查,看它是否为空。


public void DoFoo<T>(T foo) where T : ISomeInterface<T>
{
    //possible compare of value type with 'null'.
    if (foo == null) throw new ArgumentNullException("foo");
}

I'm purposely only checking against null because I don't want to restrict a ValueType from being equal to its default(T). My code compiles and works just fine this way (ReSharper complains, but not CodeAnalysis). Though I do wonder:

  • Is there a more standard way to handle this situation?
  • Is there any chance of an issue arrising from this?
  • What truly happens under the hood when I make a call and pass in a value type?

解决方案

I'm purposely only checking against null because I don't want to restrict a ValueType from being equal to its default(T)

That is a good insight, but don't worry, you are already covered there. It is not legal to compare a T against default(T) using == in the first place; overload resolution will not find a unique best == operator.

Of course, you could do the comparison with .Equals but then you run the risk of crashing if the receiver is null, which is precisely what you are attempting to avoid.

Is there a more standard way to handle this situation?

No. Comparing to null is the right thing to do here.

As the C# specification says in section 7.10.6: "The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type."

Is there any chance of an issue arrising from this?

Sure. Just because code compiles does not mean that it has the semantics you intend. Write some tests.

What truly happens under the hood when I make a call and pass in a value type?

The question is ambiguous. Let me rephrase it into two questions:

What truly happens under the hood when I make a call on the generic method with a type argument that is a non-nullable value type?

The jitter compiles the method on the first invocation with that construction. When the jitter detects the null check, it replaces it with "false" because it knows that no non-nullable value type will ever be equal to null.

What truly happens under the hood when I make a call on the generic method with a type argument that is a reference type but an argument that is a struct type? For example:

interface IFoo : ISomeInterface<IFoo> {}
struct SFoo : IFoo { whatever }
...
DoFooInternal<IFoo>(new SFoo());

In that case the jitter cannot elide the null check and the call site cannot avoid the boxing. The SFoo instance will be boxed, and the reference to the boxed SFoo will be checked to see if it is null.

这篇关于对空,可能是一个值或引用类型比较通用的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆