Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking method with custom delegate vs. action

I have seen Microsoft suggest using a custom Delegate in the InvokeRequired pattern

But I can't figure out why one wouldn't just save the trouble of defining the delegate when doing something as simple as setting a control property. I'm referring to Option 1 below which just uses the delegate Action(Of String) instead of a custom delegate.

' Option 1

Private Sub setLabelWorkingText(ByVal [text] As String)
    If Me.lblWorking.InvokeRequired Then
        Me.Invoke(New Action(Of String)(AddressOf setLabelWorkingText), [text])
    Else
        Me.lblWorking.Text = [text]
    End If
End Sub

' Option 2

Private Delegate Sub setLabelWorkingTextDelegate(ByVal [text] As String)

Private Sub setLabelWorkingTextWithDel(ByVal [text] As String)
    If Me.lblWorking.InvokeRequired Then
        Me.Invoke(New setLabelWorkingTextDelegate(AddressOf setLabelWorkingTextWithDel), [text])
    Else
        Me.lblWorking.Text = [text]
    End If
End Sub

I understand one difference to be that arguments can't be passed ByRef using Action and Func, but a custom delegate can specify ByRef arguments. Are there any other differences between the two?

like image 687
djv Avatar asked May 04 '26 13:05

djv


2 Answers

An Action is essentially a custom delegate that's defined by way of a generic. I'm guessing the reason it's not specified in the pattern you linked to is that both the pattern and the Action delegate were developed/released at the same time, and the people developing the pattern and documentation may not have been familiar with the Action generic at the time of release. You'll notice that Action is used more often in examples and patterns for later releases of the Framework, as it gained acceptance.

Also, with regards to your comment on ByRef arguments to Action and Func, this is correct, but it's also trivial to implement a custom generic Action-like class that accepts parameters ByRef, as in:

Public Delegate Sub ActionByRef(Of T)(ByRef ref As T)

Sub Main()
    Dim sMyString As String = "Hello World"
    Dim actTrim As New ActionByRef(Of String)(AddressOf TrimFirst)
    actTrim.Invoke(sMyString)
    Console.WriteLine(sMyString) 'prints "ello World"
    Console.ReadLine()
End Sub

Sub TrimFirst(ByRef s As String)
    s = s.Substring(1)
End Sub
like image 180
Flangus Avatar answered May 07 '26 03:05

Flangus


Its definitely simpler to write an Action compared to a Delegate if you can get away with it.

An Action just allows you to "pass a method as a parameter without explicitly declaring a custom delegate." Source

When you pass a lambda function I think you're adding one more line to the call stack, but meh.

like image 34
CrazyTim Avatar answered May 07 '26 03:05

CrazyTim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!