School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 300,456 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,643 people online right now. Registration is fast and FREE... Join Now!




Delegate Recipe #1

 
Reply to this topicStart new topic

> Delegate Recipe #1, Using a Delegate to Loop through a Subroutine.

AdamSpeight2008
Group Icon



post 31 Mar, 2009 - 05:25 PM
Post #1


Delegate Recipe #1
Using a Delegate to Loop through a Subroutine.

This is hard to explain in words but the example makes it a little easier to understand.
So lets begin with ForLoop Class.
CODE

Public Class ForLoop
#Region "My Private Varibles"
#Region "Integer Version"
Private m_From_Int As Integer
Private m_UpTo_Int As Integer
Private m_step_Int As Integer
Private m_del_Int As Del_Int_DoFor
#End Region
#Region "Double Version"
Private m_From_Dub As Integer
Private m_UpTo_Dub As Integer
Private m_step_Dub As Integer
Private m_del_Dub As Del_Double_DoFor
#End Region
Private IsIntegerVersion As Boolean = True
#End Region
#Region "Public Delegates"
Public Delegate Sub Del_Int_DoFor(ByVal x As Integer)
Public Delegate Sub Del_Double_DoFor(ByVal x As Double)
#End Region

#Region "Instantiation Routines"
''' <summary>
''' Creates a for-loop that loop over a subroutine.
'''
''' </summary>
''' <param name="_DoWhat">The subroutine to loop over.</param>
''' <param name="_From">Start from value</param>
''' <param name="_To">End at value</param>
''' <param name="_WithAStepOf">Using a step of.</param>
''' <remarks></remarks>
Public Sub New(ByRef _DoWhat As Del_Int_DoFor, ByVal _From As Integer, ByVal _To As Integer, Optional ByVal _WithAStepOf As Integer = Integer.MaxValue)
  If _WithAStepOf = Integer.MaxValue Then
   Select Case _From.CompareTo(_To)
    Case Is < 0 : _WithAStepOf = 1
    Case Is > 0 : _WithAStepOf = -1
    Case Is = 0 : _WithAStepOf = 1
   End Select
  End If
  Select Case _From.CompareTo(_To)
   Case Is < 0
    If _WithAStepOf <= 0 Then Throw New Exception("Incrementing For can't have a negative stepping value")
   Case Is > 0
    If _WithAStepOf >= 0 Then Throw New Exception("Decrementing For can't have a positive stepping value")
  End Select
  m_From_Int = _From
  m_UpTo_Int = _To
  m_step_Int = _WithAStepOf
  m_del_Int = _DoWhat

End Sub
Public Sub New(ByRef _DoWhat As Del_Double_DoFor, ByVal _From As Double, ByVal _To As Double, Optional ByVal _WithAStepOf As Double = Double.NaN)
  IsIntegerVersion = False
  If _WithAStepOf = Double.NaN Then
   Select Case _From.CompareTo(_To)
    Case Is < 0 : _WithAStepOf = 1
    Case Is > 0 : _WithAStepOf = -1
    Case Is = 0 : _WithAStepOf = 1
   End Select
  End If
  Select Case _From.CompareTo(_To)
   Case Is < 0
    If _WithAStepOf <= 0 Then Throw New Exception("Incrementing For can't have a negative stepping value")
   Case Is = 0
   Case Is > 0
    If _WithAStepOf >= 0 Then Throw New Exception("Decrementing For can't have a positive stepping value")

  End Select
  m_From_Dub = _From
  m_UpTo_Dub = _To
  m_step_Dub = _WithAStepOf
  m_del_Dub = _DoWhat

End Sub
#End Region
Public Sub DoForLoop()
  ' Is it the Integer Version?
  If IsIntegerVersion Then
   ' Yes, then do the integer for-loop
   For i As Integer = m_From_Int To m_UpTo_Int Step m_step_Int
    m_del_Int.Invoke(i)
   Next
  Else
   ' No, then do the double for-loop
   For i As Double = m_From_Dub To m_UpTo_Dub Step m_step_Dub
    m_del_Int.Invoke(i)
   Next
  End If
End Sub
Shared Sub ForCode(ByRef _DoWhat As Del_Int_DoFor, ByVal _From As Integer, ByVal _To As Integer, Optional ByVal _WithAStepOf As Integer = Integer.MaxValue)
  If _WithAStepOf = Integer.MaxValue Then
   Select Case _From.CompareTo(_To)
    Case Is < 0 : _WithAStepOf = 1
    Case Is > 0 : _WithAStepOf = -1
    Case Is = 0 : _WithAStepOf = 1
   End Select
  End If
  Select Case _From.CompareTo(_To)
   Case Is < 0
    If _WithAStepOf <= 0 Then Throw New Exception("Incrementing For can't have a negative stepping value")
   Case Is = 0
   Case Is > 0
    If _WithAStepOf >= 0 Then Throw New Exception("Decrementing For can't have a positive stepping value")

  End Select
  For i As Integer = _From To _To Step _WithAStepOf
   _DoWhat.Invoke(i)
  Next
End Sub
Shared Sub ForCode(ByRef _DoWhat As Del_Double_DoFor, ByVal _From As Double, ByVal _To As Double, Optional ByVal _WithAStepOf As Double = Double.NaN)
  If Double.IsNaN(_WithAStepOf) Then
   Select Case _From.CompareTo(_To)
    Case Is < 0 : _WithAStepOf = 1
    Case Is > 0 : _WithAStepOf = -1
    Case Is = 0 : _WithAStepOf = 1
   End Select
  End If
  Select Case _From.CompareTo(_To)
   Case Is < 0
    If _WithAStepOf <= 0 Then Throw New Exception("Incrementing For can't have a negative stepping value")
   Case Is = 0
   Case Is > 0
    If _WithAStepOf >= 0 Then Throw New Exception("Decrementing For can't have a positive stepping value")

  End Select
  For i As Double = _From To _To Step _WithAStepOf
   _DoWhat.Invoke(i)
  Next
End Sub
End Class


With that out the way.

What it does.
How often have you written the follow code pattern.

CODE

For i As Integer=0 To 10
SomeSub(i)
Next

What the class lets you do the same on a single line.
CODE

ForLoop.LoopCode(New Del_Int_DoFor(AddressOf SomeSub),0,10)


ForLoop.LoopCode
  • The Subroutine
    Referred to via the delegate. (In ours it New Del_Int_DoFor(AddressOf SomeSub))
  • Begin Loop At
  • End Loop At (Inclusive)
  • Optional Step Granulity
There is also an overload for looping with Doubles, but if you the delegate needs to be Del_Double_DoFor.

The Clever Stuff
Now suppose you want the do the above multiple times, I could copy and paste that line.
But this the clever bit since the it a class, I could define a variable of the class type (ForLoop) and use that.
See:
CODE

Dim My_ZeroToTen_Loop As New ForLoop(New Del_Int_DoFor(AddressOf SomeSub),0,10)

Note: The loop parameters are set in stone now and can not be altered.
What that is effectively doing is storing a forloop in a variable, which can be used and re-used later.
CODE

' Somewhere in my code I now can execute that stored loop.
My_ZeroToTen_Loop.DoLoop


Further Examples
CODE

Module Module1
Dim rn As New Random
Dim gw(5) As Integer
Dim Div5List As New List(Of Integer)

Sub Main()

  ' ForLoop.ForCode(AddressOf DivisibleBy5, -50, 50)
  ForLoop.ForCode(AddressOf DivisibleBy5, 0, 100)
   ForLoop.ForCode(AddressOf AssignRandom, LBound(gw), UBound(gw))
  ForLoop.ForCode(AddressOf PrintDub, 0.1, 10.1, 2.5)
  Dim RandomAssign As New ForLoop(AddressOf AssignRandom, LBound(gw), UBound(gw))
  RandomAssign.DoForLoop()
  printlist(gw)
Console.WriteLine()
  Console.WriteLine("Effect after Redimming")
  ReDim gw(10)
  RandomAssign.DoForLoop()
Console.WriteLine()
  printlist(gw)
  ForLoop.ForCode(AddressOf AssignRandom, LBound(gw), UBound(gw))
  printlist(gw)
  Console.ReadKey()

End Sub
Private Sub printlist(ByRef c As ICollection)
  For Each i In c
   Console.WriteLine(i)
  Next
End Sub
Private Sub DivisibleBy5(ByVal x As Integer)
  If x Mod 5 = 0 Then Div5List.Add(x)
End Sub
Private Sub AssignRandom(ByVal x As Integer)
  gw(x) = rn.Next
End Sub

Public Sub PrintDub(ByVal x As Double)
  Console.WriteLine("{0} ", x)
End Sub
Private Sub PrintOut(ByVal x As Integer)
  '  Console.WriteLine("{0} ", x)

  Dim c As New ForLoop(New ForLoop.Del_Int_DoFor(AddressOf count), 1, x)
  c.DoForLoop()
  Console.WriteLine()

End Sub

Private Sub count(ByVal x As Integer)
  Console.Write("{0} ", x)

End Sub

End Module



So you have a Delayed Execution & Reuse Weapon to add to your Code Ninja arsenal. ph34r.gif
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/8/09 02:05AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month