I've just come across a situation where a colleague wrote a bug and we didn't understand why it happened despite the fact we know how to fix it. I've been using lamda expressions for years but am much more experienced with C# than VB and I obviously have a fundamental misunderstanding of something.
The following is observed in Visual Studio 2010 with .Net 3.5.
I've simplified this down to the following simple test code that reproduced a similar scenario:
On a windows form I put the following, to simply execute a lambda and then print the value of a test object to a textbox:
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 run some code to call it using a lambda.
In the following case the output in the textbox is 15 as I would expect :
ExecuteAction(Sub(obj) obj.MyInteger = 15)
In the following case the output is also 15 as I would expect (it does generate a warning because no return value is specified which I understand and is fine 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 does the value of the object not change to 15? I need to understand this difference between single line function lambdas and multi line function lambdas to see if I need to check across all our products for similar bugs. It compiles fine and does not generate warnings making it extremely dangerous for our uses.
I tried the following to see if it made any difference forcing the execution before any implicit Return but it did not:
ExecuteAction(Function(obj) (obj.MyInteger = 15))
The difference between the multi line and the single line functions is that one contains a statement and the other contains an expression.
When obj.MyInteger = 15
is a statement then =
is the assignment operator. When it is an expression then =
is the comparison operator.
The multi line version of your single line function is:
ExecuteAction(Function(obj)
Return obj.MyInteger = 15
End Function)
This will compare the values and return a boolean value. As an Action(Of TestClass)
is expected, there is no requirement on the type of the return value, so you don't notice that it returns a boolean value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With