Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Delegates Hint

Status
Not open for further replies.

Ramo83

Programmer
Apr 7, 2005
20
IE
Hi all,
Can anyone give me a hint how can I replace a switch statement with a delegate? I'm using .net here and as I know there is no function pointers in the .net framework.
Any help would be appreciated.
Thanks.
 
Can you give us a small code sample of what it is your trying to do?

Delegates are easy in C# once you know how to do them.
 
Let's consider the following piece of code:

float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }


// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;

// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}

cout << "Switch: 2+5=" << result << endl; // display result
}

This is a switch statement that can be replaced using function pointer in c++:

void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer

cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}

How can I do this in C#? Can it be done using delegates?

Thanks a lot for the help :)
 
This is the point, where a hashtable could come in handy. I don't really see how delegates would help you here. If you come up with a delegate solution, I would be interested in seeing it.

You could also create a factory (if all your procedures are similar)

 
I don't understand how your pointer knows which operation to perform.
Marty
 
Actually I realised that I still need to use the switch statement because the pointer does not know which opcode to perform (as you said).
The thing that there's alot of cases in my code (lots of if-else or cases in the switch block), and I'm trying to find a clever approach to reduce the code and increace the performance as well.
Thanks for the help :)
 
Why not use an interface to tighten up your code.
Code:
using System;
namespace Calculator
{
	public class Calculator : IOperand
	{
		public Calculator()
		{
		}
		public float Add(float a, float b)
		{
			return a + b;
		}
		public float Subtract(float a, float b)
		{
			return a - b;
		}
		public float Multiply(float a, float b)
		{
			return a * b;
		}
		public float Divide(float a, float b)
		{
			return a/b;
		}
	}
	interface IOperand
	{
		float Add(float a, float b);
		float Subtract(float a, float b);
		float Multiply(float a, float b);
		float Divide(float a, float b);
	}
}
Code:
using System;
namespace Calculator
{
	public class ConsoleCalculator
	{
		[STAThread]
		static void Main(string[] args)
		{
			Calculator myCalculator = new Calculator();
			Console.WriteLine("Add 24 to 78 " + Convert.ToString(myCalculator.Add(24, 78)));
		}
	}
}
N.B. Did not do any exception checking.
Marty
 
Actually that's a bright idea, Thanks!
 
In the orginal question Ramo seemed to be trying to find a way to have a single method perfom many differnt types of calulations based on a flag.

The first solution as Ramo thought would be a single method that is passed a flag and based on that flag performs the correct calculation.

The second solution would be similar to what cappmgr sugested which is to wrap your different calculations up into a class and then call have the caller decide which method ( calculation ) they wanted to use.

I don't see the value in the interface in this instance though. The interface simply defines the methods that the class will contain which has no real value.

If you were going to define a few different types of calculators and they all needed to have those same methods defined in them then the interface would be the way to go to ensure that the calculators abide by the "contract" of the interface and then any caller could be assured that those methods were present in any of the calculators that they used.

A third solution would be to create an emum for your calculation types then pass the calculation type to the constructor of your calculator class, or set a property on your calculator class and call a generic calculate method. This would then read the value of the calculation type and perform the correct calculation.

I would shy away from this solution though since it could become ambiguous to the caller when using the calculator. i.e. I instanciate the calculator passing "Add"... call the calculator... do something else... then call calculator again but forget to change the "type" and instead of getting 1 * 2 I get 1 + 2.

It is much cleaner to use solution 2 where the caller calls a specific method on the class.

Just my $.02 :)

BTW if the real problem at hand is not as simple as calculation Ramo, give another example of what you are trying to accomplish. There are many ways to skin a cat in software development. The key is to get to the best one as quick as possible. :)
 
I think we are into theory now. In response to JurkMonkey wanting to see a delegate solution this is what I came up with. Ramo83 could use delegates. Like dewalt said TIMTOWTDI.
Code:
using System;

class clsDelegate
{
	public delegate float simpleDelegate (float a, float b);	
	public float Add(float a, float b)
	{
		return (a+b);
	}

	public float Multiply(float a, float b)
	{
		return (a*b);
	}
	//.....the rest

	static void Main(string[] args)
	{
		clsDelegate clsDlg = new clsDelegate();
		simpleDelegate addDelegate = new simpleDelegate(clsDlg.Add);
		simpleDelegate mulDelegate = new simpleDelegate(clsDlg.Multiply);
		float addAns = addDelegate(10,12);
		float mulAns = mulDelegate(10,10);
		Console.WriteLine("Result by calling the Add method using a delegate: {0}",addAns);
		Console.WriteLine("Result by calling the Multiply method using a delegate: {0}",mulAns);
		float addAns1 = clsDlg.Add(10,12);
		float mulAns1 = clsDlg.Multiply(10,10);
		Console.WriteLine();
		Console.WriteLine("Result by calling the Add method not using a delegate: {0}",addAns1);
		Console.WriteLine("Result by calling the Multiply method not using a delegate: {0}",mulAns1);
		Console.Read();
	}
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top