Related
I'm trying to understand Lambda expressions;
I've got a basic function Sq1 which is squaring the number i
I can rewrite this with a lambda to oneline it, Sq2
I can also write it like Sq4 with a Func<>, but I'm not sure why I'd want to
and furthermore, with Sq3 I was trying to write the long-hand version of Sq4 because writing Sq1 helped me understand what Sq2 was actually doing
public int Sq1(int i)
{
return i * i;
}
public int Sq2(int i) => i * i;
public Func<int, int> Sq3(int i)
{
// Not sure what goes here, I don't want to return a function?
}
public Func<int, int> Sq4 = x => x * x;
Can anybody help me understand why I'd write the function as per Sq4 and what this is actually shorthand for?
Sq1 and Sq2 are identical functions, not lambdas. Sq2 uses the expression body syntax that allows simplifying simple methods. Sq2 is essentially:
public int Sq2(int i) {
return i * i;
}
You can use Sharplab.io to see the generated code in both cases. You'll see that the body of both methods is the same
You can't make the Sq3 function behave like Sq4, because Sq4 on the other hand is a Func-typed field that holds the x => x * x delegate. Sq3 on the other hand is a function that returns a Func, a common idiom in functional programming.
You can use Sq4 as if it were a function, eg :
var result=Sq4(2);
As for Sq3, what you do depends on what you want to do. If you only want to execute the function, use the same syntax as Sq1 or Sq2. If you really want to return a Func<> you could use something like this :
public Func<int,int> Sq3F()
{
return (int i)=>i*i;
}
And use it like this:
var fun=Sq3F();
var result=fun(4);
Why a Func<>?
That doesn't look like much until you realize you can pass functions as parameters and construct complex transformations dynamically, eg :
public Func<int,double> LogF(Func<int,int> fun)
{
return (int i)=>Math.Log(fun(i));
}
...
var func=LogF(Sq3F());
var result=func(4);
Another common technique is partial application - take a function with multiple arguments and produce another one where some of the arguments are fixed. Let's say you want to create a single-argument Log method that works for a specific base, which means you can't just use `Math.Log(double,double). You could do this :
public Func<double,double> LogN(double N)
{
return (double d)=>Math.Log(d,N);
}
...
var log5F=LogN(5);
var result=log5F(5);
You would use the lambda expression for the sake of simplicity, to avoid having to write a full function for a simple operation.
And it would translate to the following normal function:
public int Sq4(int x):
{
return x * x;
}
Also you have used an arrow function that is different of a lambda.
An arrow function is a way to simplify the body of a function but it has the same structure
(string param1, int param2) => {
// To do here
}
This is a follow up question to How do I pass a function pointer delegate for a different class in c#
I have a class
public class ClassA
{
public void Foo()
{
Console.WriteLine("Foo()");
}
public void Foo(int x, int y)
{
Console.WriteLine("Foo(" + x.ToString() + ", " + y.ToString() + ")" );
}
public void Foo(int x, int y, int z)
{
Console.WriteLine("Foo(" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ")" );
}
}
In another method, I would like to call the class functions of classA like this:
ClassA obj = new ClassA();
TakesFun(obj.Foo);
TakesFun(obj.Foo, 1, 2);
TakesFun(obj.Foo, 1, 2, 3);
What should be the syntax of TakesFun? I would like to make it generic to take in many/any/none arguments and call the appropriate function based on the number of arguments?
Obviously below function syntax is wrong, but I am looking for one function similar to that.
public static void TakesFun<TParam>(Action<TParam[]> action, params TParam[] paramList)
{
Console.WriteLine("TakesFun");
action(paramList);
}
EDIT1: ClassA Foo functions were just an example. I would like to call more complicated functions which can take any kind of argument.
Like for eg:
public void CleanList(List<int> l)
{
l.Clear();
}
In another method, I would like to call the class functions of classA like this:
TakesFun(obj.Foo);
You go on to note that TakesFun is a single method that takes an Action, rather than a collection of overloaded methods.
You can't always get what you want, and you'll have to learn to live with the disappointment. C# does not support the feature you want.
You are converting obj.Foo from a method group form to a delegate form, and that requires that C# performs overload resolution by comparing the delegate in the formal parameter list of TakesFun with the collection of methods named Foo, and then choose the best one.
Since there is no "best one" at compile time, this will fail.
Find another way to solve your problem. Your question sounds very much like what we call an "XY problem". That is, you have some real problem, you have a crazy idea about how to solve it that will never work, and now you're asking a question about your crazy idea. Ask a question about the real problem. There's a better way to solve it than this, almost certainly.
Now, if we relax some of the constraints of your problem then we can do it. In particular, if we relax the constraint that there be only one TakesFun and that it be variadic, then we can do it. I note that TakesFun is in fact the function application operation:
static void Apply(Action action) => action();
static void Apply<A>(Action<A> action, A a) => action(a);
static void Apply<A, B>(Action<A, B> action, A a, B b) => action(a, b);
static void Apply<A, B, C>(Action<A, B, C> action, A a, B b, C c) => action(a, b, c);
... and so on, as many as you need
And now the magic of overload resolution solves your problem:
Apply(obj.Foo, 1, 2, 3); // Works fine
Overload resolution deduces that Apply means Apply<int, int, int>, that the Action is Action<int, int, int> and that the Foo meant is the one that takes three integers.
C# type inference is pretty good, but you have to use it within the bounds that we designed into the language.
UPDATE: Based on your comments it sounds like you are trying to re-invent the task parallel library. I would investigate the TPL to see if it already meets your needs.
In C# we represent the notion of a unit of work that will be performed in the future as Task; there is a huge library and built-in language support for composing workflows out of tasks, scheduling their continuations to various threads, and so on. Use this work rather than attempting to invent it yourself.
If for example you wanted to create unstarted tasks that represent future work you would do it like this:
static Task TaskFactory(Action action) => new Task(action);
static Task TaskFactory<A>(Action<A> action, A a) => new Task(()=>action(a));
static Task TaskFactory<A, B>(Action<A, B> action, A a, B b) => new Task(()=>action(a, b));
and so on. Now you can do:
Task t = TaskFactory(obj.Foo, 1, 2);
and get back a t that when started will execute the action. You can then say what you want to happen when the task is complete:
t.ContinueWith(task => Console.WriteLine("Task complete!"));
and then start it up:
t.Start();
There are mechanisms for creating tasks that are already started and run on worker threads. There are mechanisms for scheduling tasks or their completions to run on particular threads. And so on; this is a huge topic. Ask another question if you have questions about that.
What is a closure? Do we have them in .NET?
If they do exist in .NET, could you please provide a code snippet (preferably in C#) explaining it?
I have an article on this very topic. (It has lots of examples.)
In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created - i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing.
The general feature of closures is implemented in C# by anonymous methods and lambda expressions.
Here's an example using an anonymous method:
using System;
class Test
{
static void Main()
{
Action action = CreateAction();
action();
action();
}
static Action CreateAction()
{
int counter = 0;
return delegate
{
// Yes, it could be done in one statement;
// but it is clearer like this.
counter++;
Console.WriteLine("counter={0}", counter);
};
}
}
Output:
counter=1
counter=2
Here we can see that the action returned by CreateAction still has access to the counter variable, and can indeed increment it, even though CreateAction itself has finished.
If you are interested in seeing how C# implements Closure read "I know the answer (its 42) blog"
The compiler generates a class in the background to encapsulate the anoymous method and the variable j
[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
public <>c__DisplayClass2();
public void <fillFunc>b__0()
{
Console.Write("{0} ", this.j);
}
public int j;
}
for the function:
static void fillFunc(int count) {
for (int i = 0; i < count; i++)
{
int j = i;
funcArr[i] = delegate()
{
Console.Write("{0} ", j);
};
}
}
Turning it into:
private static void fillFunc(int count)
{
for (int i = 0; i < count; i++)
{
Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
class1.j = i;
Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
}
}
Closures are functional values that hold onto variable values from their original scope. C# can use them in the form of anonymous delegates.
For a very simple example, take this C# code:
delegate int testDel();
static void Main(string[] args)
{
int foo = 4;
testDel myClosure = delegate()
{
return foo;
};
int bar = myClosure();
}
At the end of it, bar will be set to 4, and the myClosure delegate can be passed around to be used elsewhere in the program.
Closures can be used for a lot of useful things, like delayed execution or to simplify interfaces - LINQ is mainly built using closures. The most immediate way it comes in handy for most developers is adding event handlers to dynamically created controls - you can use closures to add behavior when the control is instantiated, rather than storing data elsewhere.
Func<int, int> GetMultiplier(int a)
{
return delegate(int b) { return a * b; } ;
}
//...
var fn2 = GetMultiplier(2);
var fn3 = GetMultiplier(3);
Console.WriteLine(fn2(2)); //outputs 4
Console.WriteLine(fn2(3)); //outputs 6
Console.WriteLine(fn3(2)); //outputs 6
Console.WriteLine(fn3(3)); //outputs 9
A closure is an anonymous function passed outside of the function in which it is created.
It maintains any variables from the function in which it is created that it uses.
A closure is when a function is defined inside another function (or method) and it uses the variables from the parent method. This use of variables which are located in a method and wrapped in a function defined within it, is called a closure.
Mark Seemann has some interesting examples of closures in his blog post where he does a parallel between oop and functional programming.
And to make it more detailed
var workingDirectory = new DirectoryInfo(Environment.CurrentDirectory);//when this variable
Func<int, string> read = id =>
{
var path = Path.Combine(workingDirectory.FullName, id + ".txt");//is used inside this function
return File.ReadAllText(path);
};//the entire process is called a closure.
Here is a contrived example for C# which I created from similar code in JavaScript:
public delegate T Iterator<T>() where T : class;
public Iterator<T> CreateIterator<T>(IList<T> x) where T : class
{
var i = 0;
return delegate { return (i < x.Count) ? x[i++] : null; };
}
So, here is some code that shows how to use the above code...
var iterator = CreateIterator(new string[3] { "Foo", "Bar", "Baz"});
// So, although CreateIterator() has been called and returned, the variable
// "i" within CreateIterator() will live on because of a closure created
// within that method, so that every time the anonymous delegate returned
// from it is called (by calling iterator()) it's value will increment.
string currentString;
currentString = iterator(); // currentString is now "Foo"
currentString = iterator(); // currentString is now "Bar"
currentString = iterator(); // currentString is now "Baz"
currentString = iterator(); // currentString is now null
Hope that is somewhat helpful.
Closures are chunks of code that reference a variable outside themselves, (from below them on the stack), that might be called or executed later, (like when an event or delegate is defined, and could get called at some indefinite future point in time)... Because the outside variable that the chunk of code references may gone out of scope (and would otherwise have been lost), the fact that it is referenced by the chunk of code (called a closure) tells the runtime to "hold" that variable in scope until it is no longer needed by the closure chunk of code...
Basically closure is a block of code that you can pass as an argument to a function. C# supports closures in form of anonymous delegates.
Here is a simple example:
List.Find method can accept and execute piece of code (closure) to find list's item.
// Passing a block of code as a function argument
List<int> ints = new List<int> {1, 2, 3};
ints.Find(delegate(int value) { return value == 1; });
Using C#3.0 syntax we can write this as:
ints.Find(value => value == 1);
If you write an inline anonymous method (C#2) or (preferably) a Lambda expression (C#3+), an actual method is still being created. If that code is using an outer-scope local variable - you still need to pass that variable to the method somehow.
e.g. take this Linq Where clause (which is a simple extension method which passes a lambda expression):
var i = 0;
var items = new List<string>
{
"Hello","World"
};
var filtered = items.Where(x =>
// this is a predicate, i.e. a Func<T, bool> written as a lambda expression
// which is still a method actually being created for you in compile time
{
i++;
return true;
});
if you want to use i in that lambda expression, you have to pass it to that created method.
So the first question that arises is: should it be passed by value or reference?
Pass by reference is (I guess) more preferable as you get read/write access to that variable (and this is what C# does; I guess the team in Microsoft weighed the pros and cons and went with by-reference; According to Jon Skeet's article, Java went with by-value).
But then another question arises: Where to allocate that i?
Should it actually/naturally be allocated on the stack?
Well, if you allocate it on the stack and pass it by reference, there can be situations where it outlives it's own stack frame. Take this example:
static void Main(string[] args)
{
Outlive();
var list = whereItems.ToList();
Console.ReadLine();
}
static IEnumerable<string> whereItems;
static void Outlive()
{
var i = 0;
var items = new List<string>
{
"Hello","World"
};
whereItems = items.Where(x =>
{
i++;
Console.WriteLine(i);
return true;
});
}
The lambda expression (in the Where clause) again creates a method which refers to an i. If i is allocated on the stack of Outlive, then by the time you enumerate the whereItems, the i used in the generated method will point to the i of Outlive, i.e. to a place in the stack that is no longer accessible.
Ok, so we need it on the heap then.
So what the C# compiler does to support this inline anonymous/lambda, is use what is called "Closures": It creates a class on the Heap called (rather poorly) DisplayClass which has a field containing the i, and the Function that actually uses it.
Something that would be equivalent to this (you can see the IL generated using ILSpy or ILDASM):
class <>c_DisplayClass1
{
public int i;
public bool <GetFunc>b__0()
{
this.i++;
Console.WriteLine(i);
return true;
}
}
It instantiates that class in your local scope, and replaces any code relating to i or the lambda expression with that closure instance. So - anytime you are using the i in your "local scope" code where i was defined, you are actually using that DisplayClass instance field.
So if I would change the "local" i in the main method, it will actually change _DisplayClass.i ;
i.e.
var i = 0;
var items = new List<string>
{
"Hello","World"
};
var filtered = items.Where(x =>
{
i++;
return true;
});
filtered.ToList(); // will enumerate filtered, i = 2
i = 10; // i will be overwriten with 10
filtered.ToList(); // will enumerate filtered again, i = 12
Console.WriteLine(i); // should print out 12
it will print out 12, as "i = 10" goes to that dispalyclass field and changes it just before the 2nd enumeration.
A good source on the topic is this Bart De Smet Pluralsight module (requires registration) (also ignore his erroneous use of the term "Hoisting" - what (I think) he means is that the local variable (i.e. i) is changed to refer to the the new DisplayClass field).
In other news, there seems to be some misconception that "Closures" are related to loops - as I understand "Closures" are NOT a concept related to loops, but rather to anonymous methods / lambda expressions use of local scoped variables - although some trick questions use loops to demonstrate it.
A closure aims to simplify functional thinking, and it allows the runtime to manage
state, releasing extra complexity for the developer. A closure is a first-class function
with free variables that are bound in the lexical environment. Behind these buzzwords
hides a simple concept: closures are a more convenient way to give functions access
to local state and to pass data into background operations. They are special functions
that carry an implicit binding to all the nonlocal variables (also called free variables or
up-values) referenced. Moreover, a closure allows a function to access one or more nonlocal variables even when invoked outside its immediate lexical scope, and the body
of this special function can transport these free variables as a single entity, defined in
its enclosing scope. More importantly, a closure encapsulates behavior and passes it
around like any other object, granting access to the context in which the closure was
created, reading, and updating these values.
Just out of the blue,a simple and more understanding answer from the book C# 7.0 nutshell.
Pre-requisit you should know :A lambda expression can reference the local variables and parameters of the method
in which it’s defined (outer variables).
static void Main()
{
int factor = 2;
//Here factor is the variable that takes part in lambda expression.
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
Real part:Outer variables referenced by a lambda expression are called captured variables. A lambda expression that captures variables is called a closure.
Last Point to be noted:Captured variables are evaluated when the delegate is actually invoked, not when the variables were captured:
int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30
A closure is a function, defined within a function, that can access the local variables of it as well as its parent.
public string GetByName(string name)
{
List<things> theThings = new List<things>();
return theThings.Find<things>(t => t.Name == name)[0];
}
so the function inside the find method.
t => t.Name == name
can access the variables inside its scope, t, and the variable name which is in its parents scope. Even though it is executed by the find method as a delegate, from another scope all together.
I know how to use Action and Func in .NET, but every single time I start to, the exact same solution can be achieved with a regular old Method that I call instead.
This excludes when an Action or Func is used as an argument for something I don't control, like LINQ's .Where.
So basically my question is...why do these exist? What do they give me extra and new that a simple Method doesn't?
I think other answers here talk about what an Action/Func is and its use. I will try to answer how to choose between Action/Func and method. The differences first:
1) From a raw performance point of view, delegates are slower compared to direct method calls, but it's so insignificant that worrying about it is a bad practice.
2) Methods can have overloads (same function names with different signatures) but not Action/Func delegates since they are declared as variables and by C# rules you cant have two variables with the same name in a given scope.
bool IsIt() { return 1 > 2; }
bool IsIt(int i) { return i > 2; } //legal
Func<bool> IsIt = () => 1 > 2;
Func<int, bool> IsIt = i => i > 2; //illegal, duplicate variable naming
3) Consequently, Action/Func are reassignable and can point to any function, while methods once compiled remain to be the same forever. It is semantically wrong to use Func/Action if the method it points to never changes during run time.
bool IsIt() { return 1 > 2; } //always returns false
Func<bool> IsIt = () => 1 > 2;
IsIt = () => 2 > 1; //output of IsIt depends on the function it points to.
4) You can specify ref/out parameters for normal methods. For eg, you can have
bool IsIt(out string p1, ref int p2) { return 1 > 2; } //legal
Func<out string, ref int, bool> IsIt; //illegal
5) You cannot introduce new generic type parameter for Action/Func (they are generic already btw, but the type arguments can only be a known type or types specified in the parent method or class), unlike methods.
bool IsIt<A, R>() { return 1 > 2; } //legal
Func<bool> IsIt<A, R> = () => 1 > 2; //illegal
6) Methods can have optional parameters, not Action/Func.
bool IsIt(string p1 = "xyz") { return 1 > 2; } //legal
Func<string, bool> IsIt = (p1 = "xyz") => 1 > 2; //illegal
7) You can have params keyword for parameters of a method, not so with Action/Func.
bool IsIt(params string[] p1) { return 1 > 2; } //legal
Func<params string[], bool> IsIt = p1 => 1 > 2; //illegal
8) Intellisense plays well with parameter names of methods (and accordingly you have cool XML documentation available for methods), not so with Action/Func. So as far as readability is concerned, regular methods win.
9) Action/Func have a parameter limit of 16 (not that you can't define your own ones with more) but methods support more than you will ever need.
As to when to use which, I would consider the following:
When you are forced to use one based on any of the above points, then you anyway have no other choice. Point 3 is the most compelling I find upon which you will have to base your decision.
In most normal cases, a regular method is the way to go. It's the standard way of refactoring a set of common functionality in C# and VB.NET world.
As a rule of thumb, if the function is more than a line, I prefer a method.
If the function has no relevance outside a specific method and the function is too trivial, like a simple selector (Func<S, T>) or a predicate (Func<bool>) I would prefer Action/Func. For eg,
public static string GetTimeStamp()
{
Func<DateTime, string> f = dt => humanReadable
? dt.ToShortTimeString()
: dt.ToLongTimeString();
return f(DateTime.Now);
}
There could be situations where Action/Func makes more sense. For instance if you have to build a heavy expression and compile a delegate, its worth doing it only once and caching the compiled delegate.
public static class Cache<T>
{
public static readonly Func<T> Get = GetImpl();
static Func<T> GetImpl()
{
//some expensive operation here, and return a compiled delegate
}
}
instead of
public static class Cache<T>
{
public static T Get()
{
//build expression, compile delegate and invoke the delegate
}
}
In the first case when you call Get, GetImpl is executed only once, where as in the second case, (expensive) Get will be called every time.
Not to forget anonymous method itself will have certain limits unrelated to Func/Action, making the use little different. Also see this for a related question.
Action and Func are framework-provided Delegate types. Delegates allow functions to be treated like variables, meaning that you can (among other things) pass them from method to method. If you have ever programmed in C++, you can think of Delegates as function pointers that are restricted by the signature of the method they refer to.
Action and Func specifically are generic delegates (meaning they take type parameters) with some of the most common signatures- almost any method in most programs can be represented using one or the other of those two, saving people a lot of time manually defining delegates like we did in .net prior to version 2. In fact, when I see code like this in a project, I can usually safely assume that the project was migrated from .net 1.1:
// This defines a delegate (a type that represents a function)
// but usages could easily be replaced with System.Action<String>
delegate void SomeApplicationSpecificName(String someArgument);
I'd recommend that you look into delegates some more. They are a hugely powerful feature of the C# language.
I use them to create an array of functions. For instance, I may have a ComboBox full of actions that could be taken. I populate the ComboBox with items of a class or structure:
public class ComboBoxAction
{
private string text;
private Action method;
public ComboBoxAction(string text, Action method)
{
this.text = text;
this.method = method;
}
public override string ToString()
{
return this.text;
}
public void Go()
{
this.method();
}
}
Then when someone selects an item, I can call the action.
CType(ComboBox1.SelectedItem, ComboBoxAction).Go()
This is far easier than having a Select statement determine which method to call based on the ComboBox's text.
There's plenty of cases where a Func can help where a Method wouldn't.
public void DoThing(MyClass foo, Func<MyClass, string> func)
{
foo.DoSomething;
var result = func(foo);
foo.DoStringThing(result);
}
So you can specify a different Func whenever you call this method - the DoThing method doesn't need to know what's being done, just that whatever it is will return a string.
You can do this without using the Func keyword by using the delegate keyword instead; it works much the same way.
One great use of action and func are when we need to perform some operation (before or after a method), irrespective of what the method is. For example, we need to retry the method 10 times if exception occurs.
Consider the following method – its return type is generic. So it can be applied on func with any return type.
public static T ExecuteMultipleAttempts<T>(Func<T> inputMethod, Action additionalTask, int wait, int numOfTimes)
{
var funcResult = default(T);
int counter = 0;
while (counter < numOfTimes)
{
try
{
counter++;
funcResult = inputMethod();
//If no exception so far, the next line will break the loop.
break;
}
catch (Exception ex)
{
if (counter >= numOfTimes)
{
//If already exceeded the number of attemps, throw exception
throw;
}
else
{
Thread.Sleep(wait);
}
if (additionalTask != null)
{
additionalTask();
}
}
}
return funcResult;
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are your usage of delegates in C#?
Now that we have lambda expressions and anonymous methods in C#, I use delegates much more. In C# 1, where you always had to have a separate method to implement the logic, using a delegate often didn't make sense. These days I use delegates for:
Event handlers (for GUI and more)
Starting threads
Callbacks (e.g. for async APIs)
LINQ and similar (List.Find etc)
Anywhere else where I want to effectively apply "template" code with some specialized logic inside (where the delegate provides the specialization)
Delegates are very useful for many purposes.
One such purpose is to use them for filtering sequences of data. In this instance you would use a predicate delegate which accepts one argument and returns true or false depending on the implementation of the delegate itself.
Here is a silly example - I am sure you can extrapolate something more useful out of this:
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<String> names = new List<String>
{
"Nicole Hare",
"Michael Hare",
"Joe Hare",
"Sammy Hare",
"George Washington",
};
// Here I am passing "inMyFamily" to the "Where" extension method
// on my List<String>. The C# compiler automatically creates
// a delegate instance for me.
IEnumerable<String> myFamily = names.Where(inMyFamily);
foreach (String name in myFamily)
Console.WriteLine(name);
}
static Boolean inMyFamily(String name)
{
return name.EndsWith("Hare");
}
}
Found another interesting answer:
A coworker just asked me this question - what's the point of delegates in .NET? My answer was very short and one that he had not found online: to delay execution of a method.
Source: LosTechies
Just like LINQ is doing.
Delegates can often be used in place of an interface with one method, a common example of this would be the observer pattern. In other languages if you want to receive a notification that something has happened you might define something like:
class IObserver{ void Notify(...); }
In C# this is more commonly expressed using events, where the handler is a delegate, for example:
myObject.SomeEvent += delegate{ Console.WriteLine("..."); };
Another great place to use delegates if when you have to pass a predicate into a function, for example when selecting a set of items from a list:
myList.Where(i => i > 10);
The above is an example of the lambda syntax, which could also have been written as follows:
myList.Where(delegate(int i){ return i > 10; });
Another place where it can be useful to use delegates is to register factory functions, for example:
myFactory.RegisterFactory(Widgets.Foo, () => new FooWidget());
var widget = myFactory.BuildWidget(Widgets.Foo);
I hope this helps!
You can use delegates to declare function-typed variables and parameters.
Example
Consider the "resource borrowing" pattern. You want to control the creation and cleanup of a resource, while allowing client code to "borrow" the resource in between.
This declares a delegate type.
public delegate void DataReaderUser( System.Data.IDataReader dataReader );
Any method matching this signature can be used to instantiate a delegate of this type. In C# 2.0, this can be done implicitly, simply by using method's name, as well as by using anonymous methods.
This method uses the type as a parameter. Note the delegate's invocation.
public class DataProvider
{
protected string _connectionString;
public DataProvider( string psConnectionString )
{
_connectionString = psConnectionString;
}
public void UseReader( string psSELECT, DataReaderUser readerUser )
{
using ( SqlConnection connection = new SqlConnection( _connectionString ) )
try
{
SqlCommand command = new SqlCommand( psSELECT, connection );
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while ( reader.Read() )
readerUser( reader ); // the delegate is invoked
}
catch ( System.Exception ex )
{
// handle exception
throw ex;
}
}
}
The function can be called with an anonymous method as follows. Note that the anonymous method can use variables declared outside of itself. This is extremely handy (although the example is a little contrived).
string sTableName = "test";
string sQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + sTableName + "'";
DataProvider.UseReader( sQuery,
delegate( System.Data.IDataReader reader )
{
Console.WriteLine( sTableName + "." + reader[0] );
} );
I'm coming in on this really late but I was having trouble figuring out the purpose of delegates today and wrote two simple programs that give the same output that I think explains their purpose well.
NoDelegates.cs
using System;
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Test.checkInt(1);
Test.checkMax(1);
Test.checkMin(1);
Test.checkInt(10);
Test.checkMax(10);
Test.checkMin(10);
Test.checkInt(20);
Test.checkMax(20);
Test.checkMin(20);
Test.checkInt(30);
Test.checkMax(30);
Test.checkMin(30);
Test.checkInt(254);
Test.checkMax(254);
Test.checkMin(254);
Test.checkInt(255);
Test.checkMax(255);
Test.checkMin(255);
Test.checkInt(256);
Test.checkMax(256);
Test.checkMin(256);
}
}
Delegates.cs
using System;
public delegate void Valid(int a);
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
v1(1);
v1(10);
v1(20);
v1(30);
v1(254);
v1(255);
v1(256);
}
}
A slightly different use is to speed up reflection; i.e. instead of using reflection each time, you can use Delegate.CreateDelegate to create a (typed) delegate to a method (a MethodInfo), and call that delegate instead. This is then much quicker per call, as the checks have already been done.
With Expression, you can also do the same to create code on the fly - for example, you can easily create an Expression that represents the + operator for a type chosen at runtime (to provide operator support for generics, which the language doesn't provide); and you can compile an Expression to a typed delegate - job done.
Delegates are used any time you use events - that's the mechanism by which they work.
In addition, delegates are very useful for things such as using LINQ queries. For example, many LINQ queries take a delegate (often Func<T,TResult>) which can be used for filtering.
subscribing eventhandlers to events
An example might be as seen here. You have a method to process an object that meets certain requirements. However, you want to be able to process the object in multiple ways. Instead of having to create separate methods, you can simply assign a matching method that processes the object to a delegate and pass the delegate to the method that selects the objects. That way, you can assign different methods to the one selector method. I tried to make this easily understandable.
I use delegates to communicate with threads.
For example, I might have a win forms app which downloads a file. The app starts a worker thread to do the download (which prevents the GUI from locking up). The worker thread uses delegates to send status messages (eg download progress) back to the main program, so that the GUI can update the status bar.
For event handler
To pass method in a method parameters
The first line of usage is to replace the Observer/Observable (events) pattern. The second, a nice elegant version of the Strategy pattern. Various other usages can be gathered, though more esoteric than these first two I think.
Events, other anynch operations
Any time you want to encapsulate behavior, but invoke it in a uniform way. Event Handlers, call-back functions, etc. You can accomplish similar things using Interfaces and casts, but sometimes, behavior isn't necessarily tied to a type or object. Sometimes you just have behavior you need to encapsulate.
Lazy parameter initialization! Besides all previous answers (strategy pattern, observer pattern, etc), delegates allow you to handle lazy initialization of parameters. For example, suppose you have a function Download() which takes quite a lot of time and returns a certain DownloadedObject. This object is consumed by a Storage depending on a certain Conditions. Typically, you would:
storage.Store(conditions, Download(item))
However, with delegates (more precisely, lambdas) you can do the following, by changing the signature of store so that it receives a Condition and a Func<Item,DownloadedObject> and use it like this:
storage.Store(conditions, (item) => Download(item))
Therefore, storage will only evaluate the delegate if necessary, executing download depending on Conditions.
Usage of delegates
Event Handling
Multi Casting
The comparison param in In Array.Sort(T[] array, Comparison comparison), List.Sort(Comparison comparison), etc
As far as I know, delegates can be converted to function pointers. This makes life MUCH easier when interoperating with native code that takes function pointers, as they can effectively be object-orientated, even though the original programmer didn't make any provision for that to happen.
Delegate's are used to call a method by it's reference.
For example:
delegate void del_(int no1,int no2);
class Math
{
public static void add(int x,int y)
{
Console.WriteLine(x+y);
}
public static void sub(int x,int y)
{
Console.WriteLine(x-y);
}
}
class Program
{
static void Main(string[] args)
{
del_ d1 = new del_(Math.add);
d1(10, 20);
del_ d2 = new del_(Math.sub);
d2(20, 10);
Console.ReadKey();
}
}