It’s like the “Bag of Holding” for arrays

Here’s a little bit of code I find amusing. Haven’t you ever wanted an array that never ends? Or maybe better described as an array that loops? So if you have 10 items in your array and you ask for number 11, you get the first element again? I’m sure I have, but I don’t remember when or why.

Anyway, here’s a collection you can use for an (almost) infinite collection. It was actually a bit of trial and error to get the negative values to work properly.

Public Class ForeverCollection(Of T)
    Inherits Generic.List(Of T)

    Default Public Shadows ReadOnly Property Item(ByVal index As Integer) As T
            If Me.Count = 0 Then Throw New ArgumentOutOfRangeException("index")

            If index >= 0 Then
                Return MyBase.Item(Math.Abs(index Mod Me.Count))
                Return MyBase.Item(Me.Count - Math.Abs((index + 1) Mod Me.Count) - 1)
            End If

        End Get
    End Property
End Class

This uses the MOD operator which is a pretty fun bit of code. Its purpose is to return the leftover of any integer division. So 10 MOD 10 is 0, 12 MOD 10 is 2, 34 MOD 10 is 4. What good is that? Well, when you see the examples, it will make more sense.

You can use MOD for time calculations. You have 543 seconds on a timer. How many minutes and seconds is that? Which code is cooler?

allSecs = 543
min = 543 \ 60
sec = allSecs - (min * 60)
MsgBox(min & ":" & sec)or 

allSecs = 543
min = allSecs \ 60
sec = allSecs Mod 60
MsgBox(min & ":" & sec)

You can use MOD as a trigger. Lets say you have a counter and you want to annoy the user every X number of iterations.

For x As Integer = 1 To 1000
    If x Mod 15 = 0 Then
        MsgBox(String.Format("I've bugged you {0} time(s) " _
            & "and the counter is at {1}", (x / 15), x))
    End If

You can use MOD for pseudo-random seed data in SQL. MOD in SQL is "%". Take the milliseconds of the current time and mod it by different numbers.

declare @i int
set @i=0
while @i<500
    insert into userinfo(userid,createdate,logincount,
    select top 1 userid,getdate(),datepart(ms,getdate()),
        datepart(ms,getdate()) % 30,
        (datepart(ms,getdate()) % 15)*50,
        (datepart(ms,getdate()) % 25)*50,
        (datepart(ms,getdate()) % 10)*100
    from users
    order by newid()

    set @i=@i+1

I think of all the extra code I used to write before I discovered MOD and I think…

Delegatorial Rambling

I see in a sister blog a planned post regarding Delegates in .NET. I have used delegates before, and I think I have seen them misused before. But remaining on the positive, I’ll describe what the delegate capability did for me.

In an application I was writing, I made the decision to extract the product search form from the main UI application; my thought was that it would be a common element that could be used in many different applications in the long-range-planned application suite. My choice was a good one, as I did use it in multiple applications, but it did get modified along the way.

The first version was simple: you search for products, you highlight the product(s) you want, and click "Select". The search form would raise an event that the calling form would handle and process. The search form also had a button to view product details. You could highlight a product and click "View Details" to bring up another form with the product information.

This worked great until I wanted to use it in another part of the same application. In this new section, there was no "Select" function needed, only "View Details". One choice I pondered was making the Select button Public instead of Friend (remember this code is in a shared DLL now). Then the calling form could enable or disable it. I also considered making a Boolean property like HideSelect. That seemed pretty tacky. But my overall goal with designing the code was that it do what the programmer tells it and do the most obvious thing by default.

Going with that mindset, I decided the Select button will do nothing unless you give it something to do. Goodbye Event, hello Delegate. I dropped the public event and created a delegate sub that matched the signature of my old event. Then I created a private variable to hold the delegate and created a public property to Get/Set the delegate.

What benefits did this gain? I was then able to see if the calling form needed the Select button. If the private variable was Nothing, I disabled the Select button. If the private variable was a valid instance, I invoked it when the Select button was clicked. When I was using events, I couldn’t tell if anyone was subscribed to the event so I couldn’t take any action on the Select button.

Back in the calling form, the code change was minimal. Instead of doing an AddHandler statement, I created a new instance of the delegate in the search form using AddressOf in the constructor and set it to the public property on the search form. The target method that handled the event never changed.

That’s one way I used a delegate. The other way I used it was with the View Details button. For another application, the View Details was slightly different. In brief, the application needed to handle the display of the product instead of letting the search form do it. Again, I created a delegate sub, private variable and public property. In the click event of the View Details button, I checked to see if the delegate was Nothing. If it was Nothing, I performed the default action and displayed the product in the typical manner. If it was not nothing, I invoked the delegate instead of doing the default display. In this way, I was able to provide an override for default behavior.

Without using delegates, how could that have been done as easily? As I was determining how do implement the override feature, I considered using events, but that means that every calling form would have to handle that event in order to implement the default display action. That went against my design philosophy. I could have used a Boolean property, but…bleh. I insisted to myself that I would not have any shared library that required performing steps in a rigid fashion. Like, oh, the code bombed out. I forgot to call InitControls2() after setting the base properties. Yuck.

So that’s my delegate story. In summary, I used Delegates instead of Events because I was able to test to see if they were needed using IsNothing() and they provided me with a way to optionally inject a call to a remote codebase (that codebase being the calling form). Sorry for no code samples. I don’t have the code with me right now.