.Net Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming Languages - More.Net Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old May 9th, 2008, 07:50 AM
JohnFish JohnFish is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2005
Posts: 157 JohnFish User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 15 h 29 m 39 sec
Reputation Power: 4
Question about function parameter

Hi all. I have two functions A and B. Their functionality is listed below:

A does some processing stuff with the data
A loops through the data and adds their values (say int) together
A returns an int result

B does some processing stuff with the data
B loops through the data and multiplies their values (say int) together
B returns an int result

What i want to do is have one function and be able to specify what function to execute when that point reaches. Something like AB(sum)

I know this is probably done with delegates but i am not sure how.

thx

Reply With Quote
  #2  
Old May 9th, 2008, 08:08 AM
f'lar's Avatar
f'lar f'lar is offline
Senior WeyrLeader
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Aug 2003
Location: WI
Posts: 3,892 f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 5 Days 9 h 11 m 26 sec
Reputation Power: 788
Send a message via Google Talk to f'lar
C# or VB?

Here's a VB version:
Code:
    Sub Test()
        Dim data As New List(Of Integer)
        data.Add(1)
        data.Add(2)
        data.Add(3)
        data.Add(4)

        Dim product As Integer = Aggregate(data, AddressOf mult)
        Dim sum As Integer = Aggregate(data, AddressOf add)
        MsgBox("Product: " & product & vbCrLf & "Sum: " & sum)
    End Sub

    Function Aggregate(ByVal data As IEnumerable(Of Integer), ByVal method As AggregateDelegate) As Integer
        Return method(data)
    End Function

    Delegate Function AggregateDelegate(ByVal data As IEnumerable(Of Integer)) As Integer

    Function add(ByVal data As IEnumerable(Of Integer)) As Integer
        add = 0
        For Each i As Integer In data
            add += i
        Next
    End Function
    Function mult(ByVal data As IEnumerable(Of Integer)) As Integer
        mult = 1
        For Each i As Integer In data
            mult *= i
        Next
    End Function
Notice that the signatures for add() and mult() must match the signature for AggregateDelegate. The C# is even cooler because you can use anonymous methods: you don't have to declare the mult and add functions separately, but can pass the logic in line.
__________________
Primary Forums: .Net Development, MS-SQL, C Programming
VB.Net: It's not your father's Visual Basic.

[Moving to ASP.Net] | [.Net Dos and Don't for VB6 Programmers]

Last edited by f'lar : May 9th, 2008 at 08:15 AM.

Reply With Quote
  #3  
Old May 9th, 2008, 09:58 AM
WebDunce WebDunce is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2005
Location: Northwest Florida
Posts: 188 WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 3 Days 11 h 28 m 25 sec
Reputation Power: 5
...deleted by me...

Last edited by WebDunce : May 9th, 2008 at 10:22 AM.

Reply With Quote
  #4  
Old May 9th, 2008, 10:02 AM
WebDunce WebDunce is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2005
Location: Northwest Florida
Posts: 188 WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 3 Days 11 h 28 m 25 sec
Reputation Power: 5
...deleted by me...

Last edited by WebDunce : May 9th, 2008 at 10:22 AM.

Reply With Quote
  #5  
Old May 9th, 2008, 10:13 AM
WebDunce WebDunce is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2005
Location: Northwest Florida
Posts: 188 WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 3 Days 11 h 28 m 25 sec
Reputation Power: 5
Of course, another way is to have an add method and a multiply method call the common processing method.

Code:
private int[] PreProcessData(int[] data)
{
    // do some basic processing to the data
    // and return the modified data
}

public int AddThem(int[] data)
{
     int[] modifiedData = PreProcessData(data);

     int result = 0;
     for (i = 0; i < modifiedData.Length; i++)
     {
          result += modifiedData[i];
     }

     return result;
}

public int MultiplyThem(int[] data)
{
     int[] modifiedData = PreProcessData(data);

     int result = 1;
     for(int i = 0; i < modifiedData.Length; i++)
     {
          result *= modifiedData[i];
     }

     return result;
}



Now, whether you call AddThem() or MultiplyThem()...the common processing gets done. This is probably how I'd actually do it in a real program...but if you're doing an assignment you gotta do it however it was specified...I'm just showing options.

Last edited by WebDunce : May 9th, 2008 at 10:20 AM.

Reply With Quote
  #6  
Old May 9th, 2008, 10:27 AM
WebDunce WebDunce is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2005
Location: Northwest Florida
Posts: 188 WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 3 Days 11 h 28 m 25 sec
Reputation Power: 5
It's overkill for your simple goal...but another way would be to create an abstract DataProcessor class that could be subclassed to add, multiply, divide, substract...or whatever...that could be passed into the processing method.

Below I demonstrate how an abstract class would work.

Code:
// define the abstract class
public abstract class DataProcessor
{
    // just need to define one abstract method
    public abstract int GetResult(int[] data);
}

// define a class that adds
public class Adder : DataProcessor
{
     // implement the abstract method
     public override int GetResult(int[] data)
     {
          int result = 0;
          for (int i = 0; i < data.Length; i++)
          {
               result += data[i];
          }
          return result;
     }
}
 
// define a class that multiplies
public class Multiplier : DataProcessor
{
    // implement the abstract method
     public override int GetResult(int[] data)
     {
          int result = 1;
          for (int i = 0; i < data.Length; i++)
          {
               result *= data[i];
          }
          return result;
     }

}


Now...to see how the classes above would be used...

Code:
// some random method that calls your
// desired method
void SomeMethod(int[] data)
{
     // if you want to add
     int sum = ProcessData(data, new Adder());

     // if you want to multiply
     int product = ProcessData(data, new Multiplier());
}

// this is the single method that does
// the processing as required
int ProcessData(int[] data, DataProcessor dataProcessor)
{
     // do some general processing to
     // modify the data

     return dataProcessor.GetResult(data);
}




Now any object that subclasses DataProcessor can be an argument in the ProcessData method. Again, it's overkill for this problem, though.

Last edited by WebDunce : May 9th, 2008 at 10:35 AM.

Reply With Quote
  #7  
Old May 9th, 2008, 11:19 AM
f'lar's Avatar
f'lar f'lar is offline
Senior WeyrLeader
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Aug 2003
Location: WI
Posts: 3,892 f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level)f'lar User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 5 Days 9 h 11 m 26 sec
Reputation Power: 788
Send a message via Google Talk to f'lar
Lol, as long as we're going to town on this one, here's another delegate version that isolates the arithmetic operation, so you can easily do it as a lambda later if you want:
Code:
    Sub Test()
        Dim data As New List(Of Integer)
        data.Add(1)
        data.Add(2)
        data.Add(3)
        data.Add(4)

        Dim product As Integer = Aggregate(data, AddressOf mult)
        Dim sum As Integer = Aggregate(data, AddressOf add)
        MsgBox("Product: " & product & vbCrLf & "Sum: " & sum)
    End Sub

    Function Aggregate(ByVal data As IEnumerable(Of Integer), ByVal method As AggregateDelegate) As Integer
        Dim total As Integer
        Dim started As Boolean = False
        For Each i As Integer In data
            If Not started Then
                total = i
                started = True
            Else
                total = method(total, i)
            End If
        Next i
        Return total
    End Function

    Delegate Function AggregateDelegate(ByVal val1 As Integer, ByVal val2 As Integer) As Integer

    Function add(ByVal val1 As Integer, ByVal val2 As Integer) As Integer
        Return val1 + val2
    End Function

    Function mult(ByVal val1 As Integer, ByVal val2 As Integer) As Integer
        Return val1 * val2
    End Function

Notice that the test function didn't change, but if this were C# and wanted to use an anonymous function, the code would be much simpler.

Last edited by f'lar : May 9th, 2008 at 11:34 AM.

Reply With Quote
  #8  
Old May 9th, 2008, 04:43 PM
JohnFish JohnFish is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2005
Posts: 157 JohnFish User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 15 h 29 m 39 sec
Reputation Power: 4
Quote:
Originally Posted by f'lar
Lol, as long as we're going to town on this one, here's another delegate version that isolates the arithmetic operation, so you can easily do it as a lambda later if you want:
Code:
    Sub Test()
        Dim data As New List(Of Integer)
        data.Add(1)
        data.Add(2)
        data.Add(3)
        data.Add(4)

        Dim product As Integer = Aggregate(data, AddressOf mult)
        Dim sum As Integer = Aggregate(data, AddressOf add)
        MsgBox("Product: " & product & vbCrLf & "Sum: " & sum)
    End Sub

    Function Aggregate(ByVal data As IEnumerable(Of Integer), ByVal method As AggregateDelegate) As Integer
        Dim total As Integer
        Dim started As Boolean = False
        For Each i As Integer In data
            If Not started Then
                total = i
                started = True
            Else
                total = method(total, i)
            End If
        Next i
        Return total
    End Function

    Delegate Function AggregateDelegate(ByVal val1 As Integer, ByVal val2 As Integer) As Integer

    Function add(ByVal val1 As Integer, ByVal val2 As Integer) As Integer
        Return val1 + val2
    End Function

    Function mult(ByVal val1 As Integer, ByVal val2 As Integer) As Integer
        Return val1 * val2
    End Function

Notice that the test function didn't change, but if this were C# and wanted to use an anonymous function, the code would be much simpler.



Thanks for all the answers here. Actually it is c sharp but i really dont want to make it as complex as creating new classes etc. The thing is that i have a set of 10 functions that do exactly the same but are different in the way they treat data (e.g. sum, subtract, multiply, divide, etc.). I really dont want to rewrite the function 10 times. I have done the pre-processor approach mentioned earlier but i really want to use some sort of a function pointer.

Reply With Quote
  #9  
Old May 11th, 2008, 03:27 AM
WebDunce WebDunce is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2005
Location: Northwest Florida
Posts: 188 WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level)WebDunce User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 3 Days 11 h 28 m 25 sec
Reputation Power: 5
Using Delegates in C# Is Easy...

Using delegates in C# is easy; it involves 4 basic steps:
  1. Declare a delegate type. A delegate declaration follows the following formula: access modifier + delegate keyword + return type + type name {you make this part up} + (arguments). A delegate can be declared inside OR outside of classes.
    csharp Code:
    Original - csharp Code
    1. // declare the delegate
    2. public delegate int SimpleMathMethod(int value1, int value2);
  2. Make methods whose signatures match the delegate's signature. A method's signature is its return type and arguments. The access modifier (e.g., public, private, etc.) is NOT part of the signature.
    csharp Code:
    Original - csharp Code
    1. // a method with a matching signature
    2. protected int AddTwoInts(int a, int b)
    3. {
    4.     return a + b;
    5. }
    6.  
    7. // here's another one
    8. public int MultiplyTwoInts(int x, int y)
    9. {
    10.     return x * y;
    11. }
    12.  
    13. // and another one
    14. int DoCrazyPointlessStuff(int hubba, int bubba)
    15. {   
    16.     int bubbleGum = hubba + bubba; // add the two ints
    17.     bubbleGum = hubba * bubba; // multiply them
    18.     bubbleGum = hubba / bubba; // divide them
    19.     return 8; // man, those Crazy Eights :)!
    20. }
  3. Instantiate the delegates.
    csharp Code:
    Original - csharp Code
    1. // just pass the desired method's name
    2. // into the delegate's constructor
    3. SimpleMathMethod addMethod = new SimpleMathMethod(AddTwoInts);
    4. SimpleMathMethod multiplyMethod = new SimpleMathMethod(MultiplyTwoInts);
    5. SimpleMathMethod crazyMethod = new SimpleMathMethod(DoCrazyPointlessStuff);
    6.  
    7. // you don't have to do a formal variable declaration
    8. // each time. you can just instantiate it, if desired...
    9. int x = DoSomething(2, 3, new SimpleMathMethod(AddTwoInts));
  4. Use the delegates .
    csharp Code:
    Original - csharp Code
    1. // use the delegate directly...
    2. int sum1 = addMethod(1, 2);
    3. int product1 = multiplyMethod(3, 8);
    4. int crazyResult1 = crazyMethod(2, 5);
    5.  
    6. // ...or pass them into methods that can take
    7. // SimpleMathMethod objects as arguments
    8. int[] threeInts = new int[]{1, 2, 3};
    9. int sum2= ProcessSomeInts(threeInts, addMethod);
    10. int product2 = ProcessSomeInts(threeInts, multiplyMethod);
    11. int crazyResult2 = ProcessSomeInts(threeInts, crazyMethod);
    12.  
    13. // here's such a method
    14. int ProcessSomeInts(int[] someInts, SimpleMathMethod smMethod)
    15. {
    16.     int result = 0;
    17.     for (int i = 0; i < someInts.Length; i++)
    18.     {
    19.         if(i == 0)
    20.             result = someInts[i];
    21.         else
    22.             result = smMethod(result, someInts[i]); // using the delegate directly again
    23.     }
    24.     return result;
    25. }

Last edited by WebDunce : May 11th, 2008 at 04:22 AM.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - More.Net Development > Question about function parameter


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread