VB.NET 的“If”是否有效?运营商造成拳击?
我们这些曾经在 VB/VB.NET 工作过的人都见过类似这种令人厌恶的代码:
Dim name As String = IIf(obj Is Nothing, "", obj.Name)
我说“令人厌恶”是出于三个简单的原因:
IIf
是一个函数,所有参数均被评估;因此,如果上述调用中obj
没有任何内容,则将抛出NullReferenceException
。对于习惯在 C# 等语言中使用短路三元运算符的人来说,这是意想不到的行为。- 因为
IIf
是一个函数,因此会产生函数调用的开销。再说一次,虽然这不是什么大问题,但对于那些期望它表现为语言固有的三元运算的人来说,这感觉不太对劲。 IIf
是非泛型的,因此接受Object
类型的参数,这意味着以下调用框(我相信)总共三个整数:' 框出第二个和第三个参数以及返回值'
Dim value As Integer = IIf(condition, 1, -1)
现在,在 VB.NET 的某些较新版本中(我不确定数字是多少),If<引入了 /code> 运算符,其工作方式与 IIf 函数完全相同,但(据我所知)没有相同的缺点。也就是说,它确实提供短路并且它是固有的VB操作。但是,我不确定最后一部分。 MSDN 文档似乎没有表明是否
If< /code> 是否装箱其参数。有谁知道吗?
Those of us who've worked in VB/VB.NET have seen code similar to this abomination:
Dim name As String = IIf(obj Is Nothing, "", obj.Name)
I say "abomination" for three simple reasons:
IIf
is a function, all of whose parameters are evaluated; hence ifobj
is nothing in the above call then aNullReferenceException
will be thrown. This is unexpected behavior for someone who's accustomed to short-circuited ternary operators in languages like C#.- Because
IIf
is a function, it thus incurs the overhead of a function call. Again, though this isn't a big deal, it just doesn't feel right to someone who expects for it to behave as a ternary operation intrinsic to the language. IIf
is non-generic and therefore accepts parameters of typeObject
, which means the following call boxes (I believe) a total of three integers:' boxes 2nd and 3rd arguments as well as return value '
Dim value As Integer = IIf(condition, 1, -1)
Now, in some more recent version of VB.NET (I'm not sure what the number is), the If
operator was introduced, which works exactly the same way as the IIf
function but (as I understand it) without the same shortcomings. That is to say, it does provide short-circuiting and it is an intrinstic VB operation. However, I'm not sure about the last part. The MSDN documentation doesn't seem to indicate whether If
boxes its arguments or not. Does anyone know?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最主要的是您正确地将新的
If
识别为运算符而不是函数。它也是类型安全的,因此不需要装箱,并且是到条件/三元/? 的直接映射。 C/C++/C#/Java/etc 中的运算符即使没有 new 运算符,您也可以使用以下代码在 VB.Net 中获得一些改进:
The main thing is that you correctly identified the new
If
as an operator rather than a function. It is also typesafe and therefore does not need boxing, and is a direct mapping to the conditional/ternary/? operator in C/C++/C#/Java/etcEven without the new operator, you can get some improvement in VB.Net with this code:
Joel 比我先找到了答案,但这里有一个示例程序和生成的 IL,它演示了 If() 无需装箱即可传递到 IL 的底层三元运算符。
正如您所看到的,IL 没有“box”声明。
给定相同的程序但使用旧的 IIf() 函数,将生成以下 IL。您可以看到装箱和函数调用开销:
Joel beat me to an answer, but here is a sample program and the generated IL that demonstrates that If() passes through to the IL's underlying ternary operator without boxing.
As you can see the IL has no 'box' statement.
Given the same program but using the older IIf() function, the following IL is produced. You can see both the boxing, and the function call overhead: