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.
Related
I am pretty new in C# (I came from Java) and I am working on a SharePoint project.
I have the following doubt related to this method in my code:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
}
catch (Exception ex)
{
throw ex;
}
}
}
as you can see this code is executed into delegate() {...} "block":
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
What exactly means this delegate() method?
Reading here: https://learn.microsoft.com/it-it/dotnet/csharp/language-reference/keywords/delegate
it seems to me that it somethings like a way to declare an "anonymous" method where the implementation of this method is the code into the {...} block.
Is this the correct interpretation or am I missing something?
In case it is correct what is the pourpose of this delegate() method? Why I am not declaring the code into a classic method? What is it exact pourpose?
As per the documentation you referred to, the delegate keyword is used for two purposes:
To declare a delegate type
To create an anonymous method which is converted into a delegate instance
Now you could write all the code in an anonymous method in a regular method and then use a method group conversion to create a delegate instance, but that can often be annoying - particularly if you want to use any local variables or parameters in the anonymous method.
So that's why you'd use an anonymous method - or in anything from C# 3 onwards, you're more likely to use a lambda expression instead.
Consider how you'd have to create the delegate in your example if you didn't use an anonymous method or lambda expression. You'd need to write something like this:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
// Note: try/catch removed as it's pointless here, unless you're
// *trying* to obscure the stack trace in case of an exception
JobDeletionHelper helper = new JobDeletionHelper(properties);
// Note that we're using a method group conversion here - we're not
// invoking the method. We're creating a delegate which will invoke
// the method when the delegate is invoked.
SPSecurity.RunWithElevatedPrivileges(helper.DeleteJob);
}
}
// We need this extra class because the properties parameter is *captured*
// by the anonymous method
class JobDeletionHelper
{
private SPFeatureReceiverProperties properties;
internal JobDeletionHelper(SPFeatureReceiverProperties properties)
{
this.properties = properties;
}
public void DeleteJob()
{
// This is the code that was within the anonymous method
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
}
}
If you're asking about the purpose of delegates themselves, that's a slightly bigger topic - but in a nutshell, it's the ability to represent executable code as an object, so it can be passed to other code to execute. (You can think of a delegate type as being like a single-method interface, if that's useful.)
it seems to me that it somethings like a way to declare an "anonymous"
method where the implementation of this method is the code into the
{...} block.
Yes, that is on point!
In case it is correct what is the pourpose of this delegate() method?
Why I am not declaring the code into a classic method? What is it
exact pourpose?
Since you mentioned that you came from Java you can think of passing a delegate(){ ... } as passing an anonymous class in java to some extent.
In Java, an anonymous class enables you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
For example, In Java prior to JDK8 you could do:
btn.setOnAction(new EventHandler<ActionEvent>() { //<--- implementation
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
or as of JDK8:
btn.setOnAction(e -> System.out.println("Hello World!"));
Likewise in C# delegate () {...} is allowing you to pass an implementation i.e some behaviour on the fly.
It was common pattern a while back to use delegate () {...} but now you're most likely to use a lambda equivalent of () => { ... }
You may find these posts of interest:
when & why to use delegates?
Where do I use delegates?
I'm trying to restrict the return type of a generic delegate without specifying the parameter signature, and I don't know how to do this, or if it is even possible.
How can I do this or is it impossible?
My research has come up dry. Some pseudo-C# code would probably help steer you toward what I'm trying to do:
public class SomeClass< T, U > where T : Delegate // returning U
{
private someDelegate;
public SomeClass( T someDelegate )
{
this.someDelegate = someDelegate;
}
public U Run()
{
return someDelegate.DynamicInvoke();
}
}
... Elsewhere
public delegate string aDelegate();
public static string SayHi()
{
return "Hello!";
}
aDelegate greeter = SayHi;
var something = new SomeClass< aDelegate, string>( greeter );
Console.WriteLine( something.Run() ); // Should write "Hello" to the console.
I know this is a rather contrived pseudo example. I aim for a more involved usage, of course. I'm trying to write a console menu class that would associate a list of given menu options with actions that would fire depending on what option the user chooses. Right now, it just returns the string the user chose from the menu. What I'd like be able to do is return what--if anything--the associated method returns. This could perhaps be returned with the user chosen option string in a tuple... But, I figured this mini-example just cut straight to the technical hurdle I'm experiencing.
Thanks!
.NET already defines a generic delegate that returns the generic argument as it's result, Func<T>. You don't even need to define it.
public class SomeClass<U>
{
private Func<U>;
public SomeClass(Func<U> someDelegate)
{
this.someDelegate = someDelegate;
}
public U Run()
{
return someDelegate();
}
}
There's no real useful reason to allow a user of the type to provide any arbitrary delegate of the same signature. Really I'd advise you to avoid using any delegates in your code other than Func and Action (with various different numbers of generic arguments) whenever possible, as it's just creating a hassle to do so. I would consider it a reasonable restriction on any caller that has a delegate of a different type but the same signature to simply convert it to a Func<T> anyway, it's not like it's even a difficult conversion for them.
If you don't want to use Func<T> (as Servy suggests), e.g. if you have a custom delegate of your own that you want to be passed with type-safety, then perhaps you can make your custom delegate generic with respect to its return type. Then you can do it this way:
public delegate T MyDelegate<T>();
public class Foo<T>
{
private readonly MyDelegate<T> _delegate;
public Foo(MyDelegate<T> handler)
{
_delegate = handler;
}
public T Bar()
{
return _delegate();
}
}
I'm slowly getting my head around delegates, in that the signature of the delegate must match that of the method it is delegating too.
However, please review the following code.
public static void Save()
{
ThreadStart threadStart = delegate
{
SaveToDatabase();
};
new Thread(threadStart).Start();
}
private static void SaveToDatabase() { }
I am now stumped at this point, because the delegate returns void (as that is what SaveToDatabase() is) but, it's clearly returning a ThreadStart... Or is it?
If I were to write my own delegate, I would have no idea how to achieve this because the delegate would have to be void to match the return type of SaveToDatabase(). But it can't be; it would be of type ThreadStart!
My question is, have I totally mis-understood or is this made possible by some .NET trickery? If I wanted to write this method but create my own delegate, how would I ?
The word "delegate" is a bit abused. It's easier with classes and objects. A "class" is like a blueprint for an object. An "object" is an actual instance in memory, which follows the blueprint of the class.
For delegates we use the same word, hence I suspect your confusion. Consider the following code:
class Main
{
public delegate int DelegateType(string x);
public int SomeFunction(string y) { return int.Parse(y)*2; }
public void Main()
{
DelegateType delegateInstance = null;
delegateInstance = SomeFunction;
int z = delegateInstance("21");
Console.WriteLine(z);
}
}
This code outputs "42".
The DelegateType is the type of the delegate. Like a class is a blueprint for an object, the delegate is a blueprint for a function.
So later we create a variable named delegateInstance which is of the type DelegateType. To that variable, we can assign ANY function that takes a single string parameter and returns an integer. Note, that we assigned the function itself, not the results of that function. It's like the delegateInstance variable is now a synonym of that function. Indeed, as demonstrated a line later, we can now use delegateInstance to call that funcion! Just as if delegateInstance was a function itself. But, since it is variable, we can also do all the same things that we usually do with variables - like pass them as parameters to other functions, or even return from other functions (A function that returns a function! Wrap your head around that!)
OK, let's see the code that baffled you.
public static void Save()
{
ThreadStart threadStart = delegate
{
SaveToDatabase();
};
new Thread(threadStart).Start();
}
private static void SaveToDatabase() { }
First thing to notice is that you used an anonymous delegate. Another misuse of the term. When compiled, it results in something like this:
public static void Save()
{
ThreadStart threadStart;
threadStart = __ASDASDASD6546549871;
var tmp = new Thread(threadStart);
tmp.Start();
}
private static void SaveToDatabase() { }
private void __ASDASDASD6546549871()
{
SaveToDatabase();
}
Note that your anonymous function was actually transformed to a completely regular function with a random name, and then that function was assigned to the threadStart variable.
So now this is just like the example above. Just replace DelegateType with ThreadStart, delegateInstance with threadStart and SomeFunction with __ASDASDASD6546549871.
Does it make sense now?
I am now stumped at this point, because the delegate returns void (as that is what SaveToDatabase() is) but, it's clearly returning a ThreadStart... Or is it?
If I were to right my own delegate, I would have no idea how to achieve this because the delegate would have to be void to match the return type of SaveToDatabase(), but can't be because it would be of type ThreadStart!
ThreadStart is defined as a delegate. In fact, it is defined as
public delegate void ThreadStart();
So your code is not returning a delegate or a ThreadStart. It is simply defining a function that matches the ThreadStart delegate definition. The Thread constructor expects a ThreadStart delegate, which you have defined as the variable threadStart, which points to the SaveToDatabase function.
I tend to think of delegates as the old C++ term "function pointers". Delegates allow us to specify what kind of function (parameters and return type) should be passed as a parameter to another function.
My question is, have I totally mis-understood or is this made possible by some .NET trickery? If I wanted to write this method but create my own delegate, how would I ?
I think you may have misunderstood. But to answer this question specifically, the method you would write would just need to match the definition specified by the delegate type, in this case ThreadStart. That method definition must return void and accept no parameters. Your SaveToDatabase method matches this delegate type and is therefore the proper delegate method to create.
When you are going to run an administrated subProcess, the method that is going to be executed gets represented by ThreadStart or ParameterizedThreadStart, but SaveToDatabase is void and it will be executed with void signature, not with ThreadStart type.
Example from MSDN:
class Test
{
static void Main()
{
// To start a thread using a static thread procedure, use the
// class name and method name when you create the ThreadStart
// delegate. Beginning in version 2.0 of the .NET Framework,
// it is not necessary to create a delegate explicityly.
// Specify the name of the method in the Thread constructor,
// and the compiler selects the correct delegate. For example:
//
// Thread newThread = new Thread(Work.DoWork);
//
ThreadStart threadDelegate = new ThreadStart(Work.DoWork);
Thread newThread = new Thread(threadDelegate);
newThread.Start();
// To start a thread using an instance method for the thread
// procedure, use the instance variable and method name when
// you create the ThreadStart delegate. Beginning in version
// 2.0 of the .NET Framework, the explicit delegate is not
// required.
//
Work w = new Work();
w.Data = 42;
threadDelegate = new ThreadStart(w.DoMoreWork);
newThread = new Thread(threadDelegate);
newThread.Start();
}
}
class Work
{
public static void DoWork()
{
Console.WriteLine("Static thread procedure.");
}
public int Data;
public void DoMoreWork()
{
Console.WriteLine("Instance thread procedure. Data={0}", Data);
}
}
From MSDN
A delegate is a type that references a method. Once a delegate is assigned a method, it behaves exactly like that method. The delegate method can be used like any other method, with parameters and a return value, as in this example:
public delegate int PerformCalculation(int x, int y);
So return type of the delegate will match the return type of the method it is delegating.
Any method that matches the delegate's signature, which consists of the return type and parameters, can be assigned to the delegate. This makes is possible to programmatically change method calls, and also plug new code into existing classes. As long as you know the delegate's signature, you can assign your own delegated method.
Say I have a function. I wish to add a reference to this function in a variable.
So I could call the function 'foo(bool foobar)' from a variable 'bar', as if it was a function. EG. 'bar(foobar)'.
How?
It sounds like you want to save a Func to a variable for later use. Take a look at the examples here:
using System;
public class GenericFunc
{
public static void Main()
{
// Instantiate delegate to reference UppercaseString method
Func<string, string> convertMethod = UppercaseString;
string name = "Dakota";
// Use delegate instance to call UppercaseString method
Console.WriteLine(convertMethod(name));
}
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
}
See how the method UppercaseString is saved to a variable called convertMethod which can then later be called: convertMethod(name).
Using delegates
void Foo(bool foobar)
{
/* method implementation */
}
using Action delegate
Public Action<bool> Bar;
Bar = Foo;
Call the function;
bool foobar = true;
Bar(foobar);
Are you looking for Delegates?
You need to know the signature of the function, and create a delegate.
There are ready-made delegates for functions that return a value and for functions that have a void return type. Both of the previous links point to generic types that can take up to 15 or so type arguments (thus can serve for functions taking up to that many arguments).
If you intend to use references to functions in a scope larger than a local scope, you can consider defining your own custom delegates. But most of the time, Action and Func do very nicely.
Update:
Take a look at this question regarding the choice between defining your own delegates or not.
I have a recuring method which shows up many times in my code its basically checking to make sure that the connection to the odbc is ok and then connects but each time this method is called it calls another method and each instance of the main method this one is different, as each method is about 8 lines of code having it 8 times in the code isnt ideal.
so basically i would like to have just one method which i can call passing the name of the new method as an arguement.
so basically like:
private void doSomething(methodToBeCalled)
{
if(somthingistrue)
{
methodToBeCalled(someArgument)
}
}
is this possible?
thanks in advance
As already said, you can use delegates for this:
// as in the original post:
private void doSomething(Action methodToBeCalled)
{
if (somethingIsTrue)
{
methodToBeCalled();
}
}
For methods without any arguments, this method is called e.g. as follows:
private void someMethod()
{
// ...
}
doSomething(someMethod);
If you want to call a method with arguments, you can wrap a lambda function around it:
private void someMethodWithArgument(int arg)
{
// ...
}
doSomething( () => someMethodWithArgument(42) );
Of course, if your methods to be called always take the same kind of argument, you can declare your doSomething method so that it accepts an Action<T> / Action<T,T> / etc. argument instead. If you want the called methods to return a value, use a delegate from the Func<T> family instead.
You can use delegates, this is much like a pointer to a function, you can pass a delegate to the method, which will invoke it with the parameter.
public delegate void Del(string message);
// Create a method for a delegate.
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;
// Call the delegate.
handler("Hello World");
In your case
private void doSomething(Del methodToBeCalled)
{
if(somthingistrue)
{
methodToBeCalled(someArgument)
}
}
is this possible?
Delegates
use Delegates as your method argument and you can point the delegate to whichever method you want, providing you stick to your delegate signature.
You could also use reflection. Which one is better to use (reflection vs. delegates) depends on the rest of your code. If you're always calling methods that take the same parameters, then a delegate is probably most appropriate. If you need to call methods that take different parameters, then you probably have to use reflection. Looking at your question, it kind of looks like your methods take no parameters, so I'd use delegates as mentioned before.