Error caused by using function instead of sub in lambda single line expression

I just came across a situation where a colleague wrote a mistake, and we did not understand why this happened, despite the fact that we know how to fix it. I have been using lamda expressions for many years, but much more experienced with C # than VB, and I obviously have a fundamental misunderstanding of something.

In Visual Studio 2010 with .Net 3.5, the following is observed.

I simplified this to the following simple test code that reproduced a similar scenario:

In the Windows form, I put the following by simply doing a lambda, and then type the value of the test object into the text box:

Private Sub ExecuteAction(ByVal action As Action(Of TestClass)) Dim testObj As New TestClass() action(testObj) TextBox1.Text = testObj.MyInteger End Sub Public Class TestClass Public MyInteger As Integer End Class 

and then I ran the code to call it using lambda.

In the following case, the output in the text box is 15, as you would expect:

 ExecuteAction(Sub(obj) obj.MyInteger = 15) 

In the following case, the output will also be 15, as expected (it generates a warning because the return value is not specified, which I understand, and this is normal, because it does what is expected):

 ExecuteAction(Function(obj) obj.MyInteger = 15 End Function) 

In the following case, the output is 0, and I do not understand why:

 ExecuteAction(Function(obj) obj.MyInteger = 15) 

Why in the final scenario the value of the object does not change to 15? I need to understand this difference between the single-line lambdas function and the multi-line lambdas function in order to check if I need to check all our products for similar errors. It compiles perfectly and does not generate warnings, which makes it extremely dangerous for our purposes.

I tried the following to see if this had an effect on the execution before any implicit return, but it is not:

 ExecuteAction(Function(obj) (obj.MyInteger = 15)) 
+6
source share
1 answer

The difference between multi-line and single lines is that one contains an operator and the other contains an expression.

If obj.MyInteger = 15 is an operator, then = is an assignment operator. When this expression, then = is the comparison operator.

Multilinear version of your only linear function:

 ExecuteAction(Function(obj) Return obj.MyInteger = 15 End Function) 

This will compare the values ​​and return a boolean value. Since Action(Of TestClass) is expected, there is no requirement for the type of the return value, so you will not notice that it returns a boolean.

+9
source

All Articles