Magnus Bakke Magnus Bakke - 10 months ago 38 Question

How do I prevent both narrowing and late binding?

This might be a dumb question, but I just turned on Option Strict for the first time, and I'm not sure what the best approach is here.

I have a bunch of dynamically created PictureBox controls, and I'm adding event handlers when they're created to handle their paint events. In the paint event, I need to access the ClientRectangle of the PictureBox. Notice that I've changed sender As Object to sender As PictureBox:

Public Sub Example(sender As PictureBox, e As PaintEventArgs)
AlreadyExistingRectangle = sender.ClientRectangle
AlreadyExistingRectangle.Inflate(-2, -2)
' Draw stuff in AlreadyExistingRectangle
End Sub

I need the AlreadyExistingRectangle for various reasons (though I suspect there are better solutions). The reason I'm using sender as PictureBox is because my paint events are kind of slow, and I thought it might speed it up, as sender.ClientRectangle would cause late binding otherwise. But now, narrowing occurs, because the delegate sub uses sender as Object.

So, is there a simple solution, or should I just allow late binding or narrowing? And if so, which is faster?

Answer Source

I think it'd be best if you created a variable in the Paint event handler where you cast sender to a PictureBox. Then you can wrap the whole thing in a Try/Catch block to catch the cast exceptions that DirectCast throws if sender is not a PictureBox.

    Dim senderPictureBox As PictureBox = DirectCast(sender, PictureBox)
    'Do your stuff...
Catch ex As InvalidCastException
    'Either do something here or just ignore the error.
End Try

Alternatively, since throwing exceptions is costly for your already, as you state it, slow code, you could use TryCast which instead of throwing an exception just returns Nothing if the cast fails (this is much faster performance-wise).

Dim senderPictureBox As PictureBox = TryCast(sender, PictureBox)

If senderPictureBox IsNot Nothing Then
    'Do your stuff...
End If