delegates

T

tshad

I have a set up javascript functions that pass function pointers and I am
trying to figure out how to do the same thing in C# using delegates.

// We define some simple functions here
function add(x,y) {return x + y;}

function subtract(x,y) {return x - 1; }

function multiply(x,y) {return x * 1; }

function divide(x,y) {return x / 1; }



// Here's a function that takes one of the above functions

// as an argument and invokes it on two operands



function operate(operator , operand1, operand2)

{

return operator(operand1, operand2);

}



// We could invoke this function like this to compute the value of (2+3) +
(4*5)



var i = operate (add,operate(add,2,3),operate(multiply,4,5));



Here i = 25;


How would I do the same thing using delegates and is this the best way to do
this?

Thanks,

Tom
 
M

Marc Gravell

is it the best way? Well, what is wrong with:

var i = ((2+3)+(4*5));

The "operate" method isn't buying you much - this could equally be:

var i = add(add(2,3),multiply(4,5))

Where here "add"/"multiply" could be either the functions or delegate
instances pointing to those functions.

Do you have some more context on what you want to do, and why you want
to use delegates? Lots of things are possible, and I've done quite a
bit with this type of thing... but I don't want to invent a problem...

If you have .NET 3.5, System.Expression is quite useful here; but even
without it you can do this type of thing - I'm jst not sure "why"
here, so I'd rather hold-fire for mroe context...

Marc
 
M

Marc Gravell

For example using delegate instances (for whatever reason...). Note
that for "generic" maths (since you can't do this directly), I have an
implementation here:
http://www.pobox.com/~skeet/csharp/miscutil/
(look for "Generic Operators")

// for 2.0/3.0 purposes - already defined in 3.5
public delegate TResult Func<TArg1,TArg2,TResult>(
TArg1 arg1, TArg2 arg2);

static class Program {
static int Add(int x,int y) {return x+y;}
static int Subtract(int x,int y) {return x-y;}
static int Multiply (int x,int y) {return x*y;}

static void Main()
{
Func<int,int,int> add = Add, subtract = Subtract,
multiply = Multiply;
var i = add(add(2,3),multiply(4,5));
}
}


Marc
 
T

tshad

I am just trying to understand delegates better.

This was sample code in Javascript and I just wanted to see how I would do
essentially the same thing with delegates.

Here we are trying to set up a generic function where I pass a pointer to
the requested function (add, multiply, etc) and then in the function
(operate) I would use the function and operate on the other 2 parameters I
pass.

I am using 2.0 at the moment.

Thanks,

Tom
 
M

Marc Gravell

Well, if you just have a Delegate, you can invoke it with
DynamicInvoke(args), but that isn't very type safe. If you want type
safety you'll need something like I posted above. Does the post above
leave anything you are unclear on?

Marc
 
G

Göran Andersson

tshad said:
I have a set up javascript functions that pass function pointers and I am
trying to figure out how to do the same thing in C# using delegates.

Here's an example that shows how you can use delegates in different ways:


// declare a delegate:
delegate int Operator(int x, int y);

// use the delegate as argument:
private static int Operate(Operator op, int x, int y) {
return op(x, y);
}

// names methods:
private static int Add(int x, int y) { return x + y; }
private static int Mul(int x, int y) { return x * y; }
private static int Div(int x, int y) { return x / y; }

static void Main(string[] args) {

// declare delegate variables:
// assigning a method name:
Operator add = Add;
// assigning an anonumous method:
Operator sub = delegate(int x, int y) { return x - y; };

// use variables as operator argument:
Console.WriteLine(Operate(add, 1, 2));
Console.WriteLine(Operate(sub, 1, 2));
// use method names as operator argument:
Console.WriteLine(Operate(Mul, 1, 2));
Console.WriteLine(Operate(Div, 1, 2));

}
 
T

tshad

Göran Andersson said:
tshad said:
I have a set up javascript functions that pass function pointers and I am
trying to figure out how to do the same thing in C# using delegates.

Here's an example that shows how you can use delegates in different ways:


// declare a delegate:
delegate int Operator(int x, int y);

// use the delegate as argument:
private static int Operate(Operator op, int x, int y) {
return op(x, y);
}

// names methods:
private static int Add(int x, int y) { return x + y; }
private static int Mul(int x, int y) { return x * y; }
private static int Div(int x, int y) { return x / y; }

static void Main(string[] args) {

// declare delegate variables:
// assigning a method name:
Operator add = Add;
// assigning an anonumous method:
Operator sub = delegate(int x, int y) { return x - y; };

// use variables as operator argument:
Console.WriteLine(Operate(add, 1, 2));
Console.WriteLine(Operate(sub, 1, 2));
// use method names as operator argument:
Console.WriteLine(Operate(Mul, 1, 2));
Console.WriteLine(Operate(Div, 1, 2));

}

Worked Great.

I then could do this either passing the variables or using the method names
directly:

Console.WriteLine(Operate(add,Operate(Add,2,3),Operate(Mul,4,5)));

2 questions.

1) Delegates have to be defined outside of a method? I tried to define it
in main and got an error.

2) If I can just pass it directly as a method name, why would I assign it to
a variable and then pass it? When would I use the delegate and when just
passing it directly?

I am just trying to understand the pros and cons of using delegates and when
would they be best used. As events, I know but where else. And when would
it be better not to use delegates?

It's one of those things, knowing how to do something doesn't tell you
necessarily why you would use it.

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

tshad said:
1) Delegates have to be defined outside of a method? I tried to define it
in main and got an error.

Yes. A delegate declaration is declaring a type. You can't declare a
delegate type inside a method any more than you can declare a class or
a struct.
2) If I can just pass it directly as a method name, why would I assign it to
a variable and then pass it? When would I use the delegate and when just
passing it directly?

Sometimes it's clearer to use a variable, that's all. The same is true
outside delegates, of course - sometimes you don't *have* to extract
expressions before passing them as arguments, but it can be worth doing
for clarity.
I am just trying to understand the pros and cons of using delegates and when
would they be best used. As events, I know but where else. And when would
it be better not to use delegates?

It's hard to say without seeing concrete examples. I wouldn't use vast
numbers of delegates to avoid using inheritance at all, but *sometimes*
delegates can provide an easier way of specialising a type than
inheritance, for example.
 
T

tshad

Marc Gravell said:
Well, if you just have a Delegate, you can invoke it with
DynamicInvoke(args), but that isn't very type safe. If you want type
safety you'll need something like I posted above. Does the post above
leave anything you are unclear on?

Not really.

It sounds like you are talking about what we finally did in my other post
where I do both a delegate and just pass method name directly.

As you say, lots of things are possible. And I understand the mechanics of
some (pretty much). But it is another thing to know when is the best time
to use them.

Just because you can, doesn't mean you should.

This was why I was posting this to see how to do it, then when and why I
would do it (delegates).

Not sure what DynamicInvoke is, but if it isn't type safe then why do it
unless it is for variable number of parameters - which I can see a use for.

Thanks,

Tom
 
M

Marc Gravell

Not sure what DynamicInvoke is, but if it isn't type safe then why do it
unless it is for variable number of parameters - which I can see a use for.

Yes, DynamicInvoke is for calling an unknown delegate with an
arbitrary number of parameters. This is slower than the regular
Invoke, as it needs to do a lot of checks first (I don't recommend
using this here). The point being that this is arguably the only
possible purpose of your "operate" method - otherwise you can just
Invoke the delegate directly (either via del.Invoke(args), or just
del(args)).
and just pass method name directly.

For the record - you aren't passing the method name - you are passing
a delegate-instance to the method identified by name - but that code
could just as easily be (without "Operate"):

// invoke delegate instances
Console.WriteLine(add(1, 2));
Console.WriteLine(sub(1, 2));
// call methods directly
Console.WriteLine(Mul(1, 2));
Console.WriteLine(Div(1, 2));

Marc
 
G

Göran Andersson

tshad said:
I then could do this either passing the variables or using the method names
directly:

Console.WriteLine(Operate(add,Operate(Add,2,3),Operate(Mul,4,5)));

2 questions.

1) Delegates have to be defined outside of a method? I tried to define it
in main and got an error.
Yes.

2) If I can just pass it directly as a method name, why would I assign it to
a variable and then pass it? When would I use the delegate and when just
passing it directly?

You can assign the value to a variable or send it as a method argument
whenever you need another layer of abstraction. It's just like using a
string variable instead of a string literal.
I am just trying to understand the pros and cons of using delegates and when
would they be best used. As events, I know but where else. And when would
it be better not to use delegates?

There is mainly two reasons to use delegates:

1. The method to call is not known at the time you write the code that
will use it.

2. Different methods should be called in different situations.

One example is the Sort method in the List<> class. One of it's
overloads takes a delegate for a comparer, that way you can sort any
kind of data any way you like.
 
T

tshad

That helps.

Thanks,

Tom
Göran Andersson said:
You can assign the value to a variable or send it as a method argument
whenever you need another layer of abstraction. It's just like using a
string variable instead of a string literal.


There is mainly two reasons to use delegates:

1. The method to call is not known at the time you write the code that
will use it.

2. Different methods should be called in different situations.

One example is the Sort method in the List<> class. One of it's overloads
takes a delegate for a comparer, that way you can sort any kind of data
any way you like.
 
T

tshad

That helps.

Thanks,

Tom

Marc Gravell said:
Yes, DynamicInvoke is for calling an unknown delegate with an
arbitrary number of parameters. This is slower than the regular
Invoke, as it needs to do a lot of checks first (I don't recommend
using this here). The point being that this is arguably the only
possible purpose of your "operate" method - otherwise you can just
Invoke the delegate directly (either via del.Invoke(args), or just
del(args)).


For the record - you aren't passing the method name - you are passing
a delegate-instance to the method identified by name - but that code
could just as easily be (without "Operate"):

// invoke delegate instances
Console.WriteLine(add(1, 2));
Console.WriteLine(sub(1, 2));
// call methods directly
Console.WriteLine(Mul(1, 2));
Console.WriteLine(Div(1, 2));

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top