.net VB中的If()函数和委托

.net VB中的If()函数和委托,.net,vb.net,delegates,conditional-operator,.net,Vb.net,Delegates,Conditional Operator,以VB2012中的以下代码为例,我希望foo初始化为Nothing: Dim foo As Func(Of Integer) = If(True, Nothing, Function() 0) 但是,它会引发ArgumentException: Delegate to an instance method cannot have null 'this'. 我不太理解这个错误消息,但是如果我将foo的类型更改为Func(整型,整型),情况会变得非常可怕。在这种情况下,代码运行时没有错误,但是

以VB2012中的以下代码为例,我希望foo初始化为Nothing:

 Dim foo As Func(Of Integer) = If(True, Nothing, Function() 0)
但是,它会引发ArgumentException:

Delegate to an instance method cannot have null 'this'.
我不太理解这个错误消息,但是如果我将foo的类型更改为Func(整型,整型),情况会变得非常可怕。在这种情况下,代码运行时没有错误,但是foo变成了一个神秘的lambda表达式,调用它时会抛出一个NullReferenceException

如果我使用传统的If语句而不是If函数,代码将按预期工作


有人能给我解释一下这种行为吗?

看起来
IIf
工作正常:

Dim foo As Func(Of Integer) = IIf(True, Nothing, Function() 0)
但我不得不说,我不知道为什么

更新

好吧,我想我有理由。编译器将您的代码优化为以下内容:

Dim foo As Func(Of Integer) = New Func(Of Integer)(Nothing.Invoke)
这就是为什么你会得到一个例外

即使不使用
True
作为条件,也要尝试使用变量

Dim t = Integer.Parse(Console.ReadLine()) < 10
Dim foo As Func(Of Integer) = If(t, Nothing, Function() 0)
Dim t=Integer.Parse(Console.ReadLine())<10
Dim foo As Func(Of Integer)=If(t,Nothing,Function()0)
它正在转变为:

Dim foo As Func(Of Integer) = New Func(Of Integer)((If((Integer.Parse(Console.ReadLine()) < 10), Nothing, New VB$AnonymousDelegate_0(Of Integer)(Nothing, ldftn(_Lambda$__1)))).Invoke)
Dim foo As Func(Of Integer)=New Func(Of Integer)((If((Integer.Parse(Console.ReadLine())<10),Nothing,New VB$AnonymousDelegate_0(Of Integer)(Nothing,ldftn(_Lambda$u 1))。Invoke)

无论如何都会引发异常。

看起来像是编译器中的一个bug,因为此代码是等效的,但它按预期工作:

Dim f As Func(Of Integer) = Function() 0
Dim foo As Func(Of Integer) = If(True, Nothing, f)
Dim foo As Func(Of Integer) = If(True, Nothing, Nothing)
我还可以使用以下代码重现您神秘的lambda表达式:

Dim foo As Func(Of Integer) = If(True, Nothing, Function() Nothing)
这在逻辑上等同于您的语句(
无任何内容
应隐式转换为
0

这很奇怪——若编译器想要优化某个东西,我希望它能以和下面语句相同的方式进行优化。但是,以下语句的行为与预期一致:

Dim f As Func(Of Integer) = Function() 0
Dim foo As Func(Of Integer) = If(True, Nothing, f)
Dim foo As Func(Of Integer) = If(True, Nothing, Nothing)

由于
True
始终是
True
,因此此语句和您的语句应产生相同的代码。

有趣的是,我怀疑错误将是
,Nothing和lambda之间没有隐式转换。那么这是VB编译器中的错误吗?因为我仍然不明白为什么我的代码会出错。出现问题的原因是编译器转换您的
If()
语句的方式。我不确定这是一个bug还是有文档记录,但我认为这不是很直观,我希望它能工作,编译器bug。存在于VS2013中,您可以在connect.microsoft上对其进行归档。com@HansPassant:2010年和2012年。