Can methods be called via an array in C#? - c#

I have a program that will need to run different methods depending on what I want it to talk to, and I want to know if there is a way to store some sort of method pointer or something of that sort in an array. So I want an array where each element would be something like this:
[Boolean: Do_this?] [Function_pointer] [Data to pass to the function]
So basically, I can put this into a for loop and not call each function individually. Another block of code would fill in the Boolean of whether to run this function or not, and then my for loop would go through and run the function with its appropriate data if the Boolean is true.
I know delegates are similar to function pointers, but if that is the answer here, I'm not entirely sure how I would construct what I want to construct.
Is this possible in C#?

Sure is, although, to do it this way, you need all methods to have the same signature:
Lets say you had two methods:
public int Moop(string s){ return 1; }
public int Moop2(string s){ return 2; }
You could do:
var funcs = new Func<string, int>[]{ Moop, Moop2 };
And to call:
var val = funcs[0]("hello");

You could declare a specific object type to hold in a delegate, a flag that indicates whether to do that or now and the data. Note that what you are describing is very similar to events as they are also defined by a callback and some event data.
The skeletal model would look something like this, assuming all methods you want to call have the same signature (you can work around that, if you need a whole bunch of various signatures by using reflection):
// This reflects the signature of the methods you want to call
delegate void theFunction(ActionData data);
class ActionData
{
// put whatever data you would want to pass
// to the functions in this wrapper
}
class Action
{
public Action(theFunction action, ActionData data, bool doIt)
{
this.action = action;
this.data = data;
this.doIt = doIt;
}
public bool doIt
{
get;
set;
}
public ActionData data
{
get;
set;
}
public theFunction action
{
get;
set;
}
public void run()
{
if (doIt)
action(data);
}
}
And a regular use case would look something like this:
class Program
{
static void someMethod(ActionData data)
{
Console.WriteLine("SUP");
}
static void Main(string[] args)
{
Action[] actions = new Action[] {
new Action(Program.someMethod, new ActionData(), true)
};
foreach(Action a in actions)
a.run();
}
}

Yes, you can.
If all your functions share the same signature you might want to store delegates in your collection, otherwise I would go for System.Reflection.MethodInfo, which you can use later on by calling Invoke method. Parameters would be stored as array of objects - that's what Invoke expects.
If using reflection is too slow you can use Reflection.Emit to generate dynamic methods at runtime.

I would just create a List<Action>. Action is a delegate that takes no parameters and returns no results. You can use currying and lambdas such that the actual actions can call a method that has parameters. In the case where you don't actually want to run it, just don't add it to the list in the first place (or add an action that does nothing I guess).
To add an item it might look something like:
list.Add(() => someobject.someMethod(firstArgument, secondArgument));
list.Add(() => anotherObject.anotherMethod(oneArgument));
Then you can just run all of the actions when you want to:
foreach(Action action in list)
{
action();
}

This is exactly what you would use delegates for. Delegates are, more or less, type-checked function pointers. You can create some delegates and put them into an array.
Func<int, int> [] funcs = new Func<int,int>[] { x => 2 * x, x => x * x };
foreach(var fn in funcs)
{
Console.WriteLine(fn(3));
Console.WriteLine(fn(8));
}

Related

Passing a Func<int, int> to Task.Run() in C# without using lambda expressions

I try to get my head around the Task/Func/Action/await functionality of C# but still need your help:
I have a button click event handler in my gui thread that, when called, does the following:
Func<int> t = new Func<int>(CountToBillion);
int result = await Task.Run(t);
//do something with result value...
The method itself is declared as:
private int CountToBillion()
{
//count to 1 billion and return 0
}
So far, this runs without error. But if I want to pass a parameter to CountToBillion() everything I try goes horribly wrong.
Func<int, int> t = new Func<int, int>(CountToBillion);
int result = Task.Run(t???);
// ...
private int CountToBillion(int workerId)
{
//count to 1 billion and return 0
}
For now, I would like to NOT use lambda expressions, because I do not understand them yet. I always see this solution:
await Task.Run(() => methodcall(...));
But there must be away to use this without lambda expressions, or am I completely off track here? How would I use Task.Run() with plain old simple objects?
The Task.Run method doesn't have an overload that allows you to take a Func<T, R>.
You can use a closure, but that's something you say you don't want to use, just for practice sake:
var someInput = 42;
// And there are side-effects to calling the Result property getter
// but that's a totally different issue I am ignoring for now
// because it depends on the application context
var result = Task.Run(() => CountToBillion(someInput)).Result;
So then, re-structure your code. Do what the C# compiler does to closures. Do that transformation yourself manually.
So instead of writing your CountToBillion method like so:
public static void Main(string[] args)
{
}
static int CountToBillion(int someInput) { ... }
Do this:
public static void Main(string[] args)
{
var foo = new Foo(42);
var result = Task.Run(foo.CountToBillion).Result;
}
class Foo
{
public Foo(int someInput) { SomeInput = someInput; }
public int SomeInput { get; set; }
public int CountToBillion() { ... }
}
I am skeptical of your desire to avoid the use of anonymous methods or lambda expressions. They are convenient, idiomatic, and functionally you're going to wind up doing something that is essentially the same anyway, but without the compiler's help.
You can read the Task.Run() docs as well as anyone else, I presume, so you can easily see that there's not any overload for that method that provides for a parameterized invocation of the task delegate. So you will need to provide that for yourself.
You can do it exactly the same way that the C# compiler would do it for you, if you'd be willing to use a lambda expression. In particular, you would need to declare a type to hold the parameter, and which has a suitable method to use for the task invocation.
For example:
class CountToBillionWrapper
{
private readonly int _workerId;
public CountToBillionWrapper(int workerId)
{
_workerId = workerId;
}
public int CountToBillion()
{
// do whatever, using the _workerId field as if it had been passed to the method
}
}
Then you can do this:
CountToBillionWrapper wrapper = new CountToBillionWrapper(workerId);
int result = await Task.Run(wrapper.CountToBillion);
Since this is, essentially, how the C# compiler implements a closure that would be needed when using a lambda expression that captures the variables that you want to pass to the method, I don't really see the point in doing it this way. Seems like extra work for harder-to-read code to me.
But maybe you prefer the explicitness. If so, the above will work to do what you're asking.

Does C# have a concept of methods inside of methods?

I have been using javascript and I made a lot of use of functions inside of functions. I tried this in C# but it seems they don't exist. If I have the following:
public abc() {
}
How can I code a method d() that can only be called
from inside the method the method abc() ?
I wouldn't worry so much about the restriction of access to a method on the method level but more class level, you can use private to restrict access of the method to that specific class.
Another alternative would be to use lambdas/anonymous methods, or if you're using C# 4.0, Action/Tasks to create them inside your method.
An example of an anonymous method using a delegate (C# 1/2/3/4) for your specific example (incl. I need an action that can take a string parameter and return a string?) would be something like this:
delegate string MyDelegate(string);
public void abc() {
// Your code..
MyDelegate d = delegate(string a) { return a + "whatever"; };
var str = d("hello");
}
.. using C# 3/4:
public void abc() {
// Your code..
Func<string, string> d = (a) => { return a + "whatever"; };
var str = d("hello");
}
.. using a more ideal solution through private method:
private string d(string a)
{
return a + "whatever";
}
public void abc()
{
// Your code..
var str = d("hello");
}
Based on your comment for another answer: I would just like to have this at the bottom of the method and then call it from some earlier code.
This won't be possible, you would need to define a variable for your method using either delegates or Actions and so it would need to be fully initialised by time you call it. You wouldn't then be able to define this at the bottom of your method. A much better option would be to simply create a new private method on your class and call that.
It is not the way to define classes, but you could do:
public abc() {
Action d = () => {
// define your method
};
d();
}
You cannot declare a method inside another method, but you can create anonymous functions inside methods:
public void abc()
{
Action d = () => { ... };
// ...
d();
}
... that can only be called from inside the method the method abc() ?
The method can only be called if you have a reference to it. If you don't store the reference elsewhere then you should be fine.
how can I pass and return a string to the action?
Use a Func instead of an Action:
Func<string, string> d = s => {
return s + "foo";
};
The reason I would like to do this is to make my code more readable.
It's good to try to make your code more readable but I think this change will make it less readable. I suggest you use ordinary methods, and not anonymous functions. You can make them private so that they cannot be called from outside your class.
Use action delegates. More effective than you did.
public abc() {
Action <int> GetInt = (i) =>
{
//Write code here
Console.Writeline("Your integer is: {0}", i);
};
GetInt(10);
}
Action is a delegate so you can give parameter as a method, not variable. Action delegate encapsulates a method that has no parameters and does not return a value. Check it from MSDN.
Yes, they are called delegates and anonymous methods.
Delegate signatures must be predefined outside of the method for the body to be assigned, so it's not exactly like a function. You would first declare a delegate:
class MyClass {
public delegate boolean Decider(string message);
/* ... */
}
And then in MyClass.MyMethod you can say Decider IsAllLowerCase = /* method name or anonymous method */; and then use it with var result = IsAllLowerCase(s);.
The good news is that .NET already has delegate definitions for most signatures you could possibly need. System.Action has assorted signatures for methods which do not return anything, and System.Func is for the ones that do.
As shown elsewhere,
Action<int, string> a = (n, s) => { for(var i=0; i<n; i++) Console.WriteLine(s);};
Allows you to call a( /* inputs */ ); as if it was a local variable. (stuff) => { code } is "lambda expression" or an anonymous method, you can also just pass a name of a method (if the signature matches):
Action<string> a = Console.WriteLine;
If you want to return something, use Func:
Func<bool, string> f = (b) => { return b.ToString(); };
Allows you to call var result = f(b); in the same way.
As a footnote, delegates are a fun part of C#/.NET but usually, the way to control access is to make another method inside your class, and declare it private. If your issue is name conflicts, then you might want to refactor. For example, you can group methods in another class declared inside your original class (nested classes are supported) or move them to another class entirely.
You can use action delegates
public abc() {
Action action = () =>
{
//Your code here
}
action();
}
Edit: To pass parameter
public abc() {
Action <string>action = (str) =>
{
//Your code here
};
}
action("hello");
Using Func to return a value
public void abc() {
Func<string, string> func = (str) => { return "You sent " + str; };
string str = func("hello");
}
You CAN create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
Then yu can call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.

Call/Invoke a method based on a string value contained in an array [duplicate]

This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 1 year ago.
I have a struct-array that contains details of different reports that can be run. Each report calls a different method and currently the program has to manually check the selected report value to specifically call the appropriate method.
I would like to store the method name in the struct-array and then have program invoke that method when there is match. Is this possible?
Currently:
if (this.cboSelectReport.Text == "Daily_Unload")
{
reportDailyUnload();
}
Ideally:
if(this.cboSelectReport.Text == MyArray[i].Name)
{
something(MyArray[i].MethodName);
}
UPDATE
I tired a number of the suggestions below and none of them worked. They didn't work probably due to how I have my program structured.
You can do it using reflection, but IMO it is too fragile: it introduces an invisible dependency on the name of the method that you call.
// Assuming that the method is static, you can access it like this:
var namedReportMethod = "MyReport1";
var reportMethod = typeof(ReporterClass).GetMethod(namedReportMethod);
var res = reportMethod.Invoke(null, new object[] {reportArg1, reportArg2});
A better approach would be to define a delegate based on your method, and store it in the struct/class instead of the method name.
delegate void ReportDelegate(int param1, string param2);
class Runner {
public static void RunReport(ReportDelegate rd) {
rd(1, "hello");
}
}
class Test {
static void TestReport(int a, string b) {
// ....
}
public static void Main(string[] args) {
Runner.RunReport(TestReport);
}
}
Instead of defining your own delegate types, you can use pre-defined ones based on Action<T1,T2,...> or Func<T1,T2,R>, depending on your need to return values from the reports.
Rather than storing the method name, you could store a delegate:
struct ReportInfo
{
public string Name { get; set; }
public Action Method { get; set; }
}
//...
MyArray[0] = new ReportInfo { Name = "Daily_Unload", Action = this.reportDailyUnload };
//...
if(this.cboSelectReport.Text == MyArray[i].Name)
{
MyArray[i].Method.Invoke();
}
Most people seem to prefer the alternative syntax where you can invoke a delegate as if it were a method, using a list of arguments in parentheses. I tend to avoid this, because it can be ambiguous whether the thing being invoked is a method or a delegate:
MyArray[i].Method();
In this case, we're invoking the delegate that is referred to by the Method property, but this code could also represent a call to a method called "Method". Confusing.
As for me, supporting simple switch is much easier than dealing with reflection, array of method names or delegates, and invoking that stuff:
switch (reportType)
{
case "Daily_Unload":
ReportDailyUnload();
break;
// ...
}
If all the methods share the same signature, one way would be to cache a delegate:
// initialize, maybe in a constructor
Dictionary<string, Action> nameDelegateMapping = new Dictionary<string, Action>();
// setup the delegates
nameDelegateMapping.Add("Daily_Unload", reportDailyUnload);
// ... add more methods here.
// later
string methodName = this.cboSelectReport.Text;
Action action;
if (nameDelegateMapping.TryGetValue(methodName, out action))
{
action();
}
else
{
// tell user the method does not exist.
}
Yes, what you are talking about is reflection. Here is an article on how to invoke a method. There is a lot you can find on reflection using google.
Add a delegate property to your struct (e.g. of type Action) then just invoke this delegate when you need it. Just set this property to the method you want to call when instantiating the struct instances.
Using a delegate and dictionary<string, delegate>
void Main()
{
var reports = new Dictionary<string, Report>
{
{"Daily_Unload", ReportDailyUnLoad}
};
var report = "Daily_Unload";
reports[report]();
}
delegate string Report();
string ReportDailyUnLoad()
{
return "daily unload report";
}

What is the purpose of delegates in .NET

So I'm a little bit confused about delegates in C#.... what do they do and how are they useful? I've read a few tutorials, and I don't really get exactly what they're supposed to do (everyone relates them to function pointers in C, and I've never programmed in C).
So... what do delegates do? What's a scenario in which I should use them? How would I then use them?
The other answers are good, but here's another way to think about delegates that might help. Imagine that a delegate is nothing more than an interface. When you see:
delegate void Action();
think:
interface IAction
{
void Invoke();
}
And when you see:
Action myAction = foo.Bar;
think:
class FooBarAction : IAction
{
public Foo Receiver { get; private set; }
public FooBarAction(Foo foo)
{
this.Receiver = foo;
}
public void Invoke()
{
this.Receiver.Bar();
}
}
...
IAction myAction = new FooBarAction(foo);
And when you see
myAction();
think
myAction.Invoke();
The actual details of what types get constructed are a bit different, but fundamentally that's what's happening. A delegate is simply an object with a method called Invoke, and when you call that method, it calls some other method on some other object on your behalf. That's why it's called a "delegate" -- because it delegates the call to another method of another object.
Delegates are sort of like objects that represent a method call. One useful way they can be used are as callbacks. For example, imagine you have a method that does something asynchronous, and you want the caller to be able to specify what they want to happen once it completes (Action is a type of delegate):
public void DoSomething(Action whatToDoWhenDone)
{
// Your code
// See how the delegate is called like a method
whatToDoWhenDone();
}
A user of DoSomething can now specify the callback as a parameter:
public void AnotherMethod()
{
DoSomething(ShowSuccess); // ShowSuccess will be called when done
}
public void ShowSuccess()
{
Console.WriteLine("Success!");
}
You can also use lamba expressions as a shorter way of writing your delegate:
public void AnotherMethod()
{
DoSomething(() => Console.WriteLine("Success!"));
// Also DoSomething(delegate() { Console.WriteLine("Success!"); });
}
Callbacks are far from the only use cases for delegates. Hopefully this shows you some of their power: the ability to have code to be executed as a variable.
Delegates allow you to treat functions as if they were any other variable. A delegate type defines the signature of the function, that is, what the function returns, and the number and type of arguments that it takes:
// This is the delegate for a function that takes a string and returns a string.
// It can also be written using the framework-provided Generic delegate Func, as
// Func<String, String>
delegate String StringToStringDelegate(String input);
You can define a variable of this type, and assign it to an existing method. I use the generic as an example, because that is the more common usage in .net since 2.0:
String Reverse(String input) {
return input.Reverse();
}
Func<String, String> someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(someStringMethod("abc"));
You can also pass functions around this way:
String Reverse(String input) {
return input.Reverse();
}
String UpperCase(String input) {
return input.ToUpper();
}
String DoSomethingToABC(Func<String, String> inputFunction) {
return inputFunction("abc");
}
var someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(DoSomethingToABC(someStringMethod));
var someOtherStringMethod = new Func<String, String>(UpperCase);
// Prints "ABC":
Console.WriteLine(DoSomethingToABC(someOtherStringMethod));
In a big application it is often required to other parts of the application based on some condition or something else. The delegate specifies the address of the method to be called. In simple manner a normal event handler implements the delegates in the inner layers.
The oversimplified answer is that a delegate is basically a "pointer" to a block of code, and the benefit is that you can pass this block of code into other functions by assigning your block of code to a variable.
The reason people relate Delegates to C function pointers is because this is in essence what delegation is all about, I.e.: Pointers to methods.
As an example:
public void DoSomething(Action yourCodeBlock)
{
yourCodeBlock();
}
public void CallingMethod()
{
this.DoSomething(
{
... statements
});
this.DoSomething(
{
... other statements
});
}
There are naturally lots of ways to invoke delegates as all of the tutorials will show you. The point is though that it allows you to "delegate" functionality in such a way that you can call into methods without necessarily knowing how they work, but simply trusting that they will be taken care of. In other words, I might create a class that implements a "DoSomething()" function, but I can leave it up to someone else to decide what DoSomething() will do later on.
I hope that helps. :-)
Delegates are a way to call back into your code when a long running operation completes or when an event occurs. For example, you pass a delegate to a method that asynchronously downloads a file in the background. When the download is complete, your delegate method would be invoked and it could then take some action such as processing the file's contents.
An event handler is a special type of delegate. For example, an event handler delegate can respond to an event like a mouse click or key press. Events are by far the most common type of delegate. In fact, you will typically see the event keyword used far more often in C# code than the delegate keyword.
You can think of it as a type in which you may store references to functions. That way you can in effect, store a function in a variable so you may call it later like any other function.
e.g.,
public delegate void AnEmptyVoidFunction();
This creates a delegate type called AnEmptyVoidFunction and it may be used to store references to functions that return void and has no arguments.
You could then store a reference to a function with that signature.
public static void SomeMethod() { }
public static int ADifferentMethod(int someArg) { return someArg; }
AnEmptyVoidFunction func1 = new AnEmptyVoidFunction(SomeMethod);
// or leave out the constructor call to let the compiler figure it out
AnEmptyVoidFunction func2 = SomeMethod;
// note that the above only works if it is a function defined
// within a class, it doesn't work with other delegates
//AnEmptyVoidFunction func3 = new AnEmptyVoidFunction(ADifferentMethod);
// error wrong function type
Not only can it store declared functions but also anonymous functions (i.e., lambdas or anonymous delegates)
// storing a lambda function (C#3 and up)
AnEmptyVoidFunction func4 = () => { };
// storing an anonymous delegate (C#2)
AnEmptyVoidFunction func5 = delegate() { };
To call these delegates, you can just invoke them like any other function call. Though since it is a variable, you may want to check if it is null beforehand.
AnEmptyVoidFunction func1 = () =>
{
Console.WriteLine("Hello World");
};
func1(); // "Hello World"
AnEmptyVoidFunction func2 = null;
func2(); // NullReferenceException
public static void CallIt(AnEmptyDelegate func)
{
// check first if it is not null
if (func != null)
{
func();
}
}
You would use them any time you needed to pass around a method that you wish to invoke. Almost in the same way that you may pass instances of objects so you may do what you wish with them. The typical use case for delegates is when declaring events. I have written another answer describing the pattern so you can look at that for more information on how to write those.

Delegates, Why? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When would you use delegates in C#?
The purpose of delegates
I have seen many question regarding the use of delegates. I am still not clear where and WHY would you use delegates instead of calling the method directly.
I have heard this phrase many times: "The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked."
I don't understand how that statement is correct.
I've written the following examples. Let's say you have 3 methods with same parameters:
public int add(int x, int y)
{
int total;
return total = x + y;
}
public int multiply(int x, int y)
{
int total;
return total = x * y;
}
public int subtract(int x, int y)
{
int total;
return total = x - y;
}
Now I declare a delegate:
public delegate int Operations(int x, int y);
Now I can take it a step further a declare a handler to use this delegate (or your delegate directly)
Call delegate:
MyClass f = new MyClass();
Operations p = new Operations(f.multiply);
p.Invoke(5, 5);
or call with handler
f.OperationsHandler = f.multiply;
//just displaying result to text as an example
textBoxDelegate.Text = f.OperationsHandler.Invoke(5, 5).ToString();
In these both cases, I see my "multiply" method being specified. Why do people use the phrase "change functionality at runtime" or the one above?
Why are delegates used if every time I declare a delegate, it needs a method to point to? and if it needs a method to point to, why not just call that method directly? It seems to me that I have to write more code to use delegates than just to use the functions directly.
Can someone please give me a real world situation? I am totally confused.
Changing functionality at runtime is not what delegates accomplish.
Basically, delegates save you a crapload of typing.
For instance:
class Person
{
public string Name { get; }
public int Age { get; }
public double Height { get; }
public double Weight { get; }
}
IEnumerable<Person> people = GetPeople();
var orderedByName = people.OrderBy(p => p.Name);
var orderedByAge = people.OrderBy(p => p.Age);
var orderedByHeight = people.OrderBy(p => p.Height);
var orderedByWeight = people.OrderBy(p => p.Weight);
In the above code, the p => p.Name, p => p.Age, etc. are all lambda expressions that evaluate to Func<Person, T> delegates (where T is string, int, double, and double, respectively).
Now let's consider how we could've achieved the above without delegates. Instead of having the OrderBy method take a delegate parameter, we would have to forsake genericity and define these methods:
public static IEnumerable<Person> OrderByName(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByAge(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByHeight(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByWeight(this IEnumerable<Person> people);
This would totally suck. I mean, firstly, the code has become infinitely less reusable as it only applies to collections of the Person type. Additionally, we need to copy and paste the very same code four times, changing only 1 or 2 lines in each copy (where the relevant property of Person is referenced -- otherwise it would all look the same)! This would quickly become an unmaintainable mess.
So delegates allow you to make your code more reusable and more maintainable by abstracting away certain behaviors within code that can be switched in and out.
.NET Delegates: A C# Bedtime Story
Delegates are extremely useful, especially after the introduction of linq and closures.
A good example is the 'Where' function, one of the standard linq methods. 'Where' takes a list and a filter, and returns a list of the items matching the filter. (The filter argument is a delegate which takes a T and returns a boolean.)
Because it uses a delegate to specify the filter, the Where function is extremely flexible. You don't need different Where functions to filter odd numbers and prime numbers, for example. The calling syntax is also very concise, which would not be the case if you used an interface or an abstract class.
More concretely, Where taking a delegate means you can write this:
var result = list.Where(x => x != null);
...
instead of this:
var result = new List<T>();
foreach (var e in list)
if (e != null)
result.add(e)
...
Why are delegates used if everytime I
declare a delegate, it needs a method
to point to? and if it needs a method
to point to, why not just call that
method directly?
Like interfaces, delegates let you decouple and generalize your code. You usually use delegates when you don't know in advance which methods you will want to execute - when you only know that you'll want to execute something that matches a certain signature.
For example, consider a timer class that will execute some method at regular intervals:
public delegate void SimpleAction();
public class Timer {
public Timer(int secondsBetweenActions, SimpleAction simpleAction) {}
}
You can plug anything into that timer, so you can use it in any other project or applications without trying to predict how you'll use it and without limiting its use to a small handful of scenarios that you're thinking of right now.
Let me offer an example. If your class exposes an event, it can be assigned some number of delegates at runtime, which will be called to signal that something happened. When you wrote the class, you had no idea what delegates it would wind up running. Instead, this is determined by whoever uses your class.
One example where a delegate is needed is when you have to modify a control in the UI thread and you are operating in a different thread. For example,
public delegate void UpdateTextBox(string data);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
...
Invoke(new UpdateTextBox(textBoxData), data);
...
}
private void textBoxData(string data)
{
textBox1.Text += data;
}
In your example, once you've assigned a delegate to a variable, you can pass it around like any other variable. You can create a method accepting a delegate as a parameter, and it can invoke the delegate without needing to know where the method is really declared.
private int DoSomeOperation( Operations operation )
{
return operation.Invoke(5,5);
}
...
MyClass f = new MyClass();
Operations p = new Operations(f.multiply);
int result = DoSomeOperation( p );
Delegates make methods into things that you can pass around in the same way as an int. You could say that variables don't give you anything extra because in
int i = 5;
Console.Write( i + 10 );
you see the value 5 being specified, so you might as well just say Console.Write( 5 + 10 ). It's true in that case, but it misses the benefits for being able to say
DateTime nextWeek = DateTime.Now.AddDays(7);
instead of having to define a specifc DateTime.AddSevenDays() method, and an AddSixDays method, and so on.
To give a concrete example, a particularly recent use of a delegate for me was SendAsync() on System.Net.Mail.SmtpClient. I have an application that sends tons and tons of email and there was a noticeable performance hit waiting for the Exchange server to accept the message. However, it was necessary to log the result of the interaction with that server.
So I wrote a delegate method to handle that logging and passed it to SendAsync() (we were previously just using Send()) when sending each email. That way it can call back to the delegate to log the result and the application threads aren't waiting for the interaction to finish before continuing.
The same can be true of any external IO where you want the application to continue without waiting for the interaction to complete. Proxy classes for web services, etc. take advantage of this.
You can use delegates to implement subscriptions and eventHandlers.
You can also (in a terrible way) use them to get around circular dependencies.
Or if you have a calculation engine and there are many possible calculations, then you can use a parameter delegate instead of many different function calls for your engine.
Did you read http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx ?
Using your example of Operations, imagine a calculator which has several buttons.
You could create a class for your button like this
class CalcButton extends Button {
Operations myOp;
public CalcButton(Operations op) {
this.myOp=op;
}
public void OnClick(Event e) {
setA( this.myOp(getA(), getB()) ); // perform the operation
}
}
and then when you create buttons, you could create each with a different operation
CalcButton addButton = new CalcButton(new Operations(f.multiply));
This is better for several reasons. You don't replicate the code in the buttons, they are generic.
You could have multiple buttons that all have the same operation, for example on different panels or menus. You could change the operation associated with a button on the fly.
Delegates are used to solve an Access issue. When ever you want to have object foo that needs to call object bar's frob method but does not access to to frob method.
Object goo does have access to both foo and bar so it can tie it together using delegates. Typically bar and goo are often the same object.
For example a Button class typically doesn't have any access to the class defines a Button_click method.
So now that we have that we can use it for a whole lot things other than just events. Asynch patterns and Linq are two examples.
It seems many of the answers have to do with inline delegates, which in my opinion are easier to make sense of than what I'll call "classic delegates."
Below is my example of how delegates allow a consuming class to change or augment behaviour (by effectively adding "hooks" so a consumer can do things before or after a critical action and/or prevent that behaviour altogether). Notice that all of the decision-making logic is provided from outside the StringSaver class. Now consider that there may be 4 different consumers of this class -- each of them can implement their own Verification and Notification logic, or none, as appropriate.
internal class StringSaver
{
public void Save()
{
if(BeforeSave != null)
{
var shouldProceed = BeforeSave(thingsToSave);
if(!shouldProceed) return;
}
BeforeSave(thingsToSave);
// do the save
if (AfterSave != null) AfterSave();
}
IList<string> thingsToSave;
public void Add(string thing) { thingsToSave.Add(thing); }
public Verification BeforeSave;
public Notification AfterSave;
}
public delegate bool Verification(IEnumerable<string> thingsBeingSaved);
public delegate void Notification();
public class SomeUtility
{
public void SaveSomeStrings(params string[] strings)
{
var saver = new StringSaver
{
BeforeSave = ValidateStrings,
AfterSave = ReportSuccess
};
foreach (var s in strings) saver.Add(s);
saver.Save();
}
bool ValidateStrings(IEnumerable<string> strings)
{
return !strings.Any(s => s.Contains("RESTRICTED"));
}
void ReportSuccess()
{
Console.WriteLine("Saved successfully");
}
}
I guess the point is that the method to which the delegate points is not necessarily in the class exposing the delegate member.

Categories

Resources