I understand that a declaration of a delegate is something like this:
public delegate int PerformCalculation(int x, int y);
However, there must be more going on. The purpose of the delegate is to provide a pointer to a method, and to do that you encapsulate the reference to the method in the delegate.
What kind of structure is this reference held in (internally in the delegate)? I also understand that you can encapsulate a reference to multiple methods in a delegate. Does this mean that there is an array in the delegate that holds these?
Also, what methods are defined in the delegate, etc. What is really happening when you declare a delegate with the terse:
public delegate int PerformCalculation(int x, int y);
?
EDIT: Some clarification. When you declare a delegate, the compiler automatically creates a sealed class that inherits from System.MulticastDelegate for you. You can see this if you look at your assembly with ildasm. This neat. Basically, with one statement, you are getting an entire new class generated for you at compile time, and it has all the functionality you need.
In the . NET environment, a delegate is a type that defines a method signature and it can pass a function as a parameter. In simple words we can say delegate is a . NET object which points to a method that matches its specific signature.
On declaring the delegate a class called del will get created. The signature of del need not be same as the signature of the method that we intend to call using it. The del class will be derived from the MulticastDelegate class. The method that can be called using del should not be a static method.
Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void: C# Copy.
Internally it's a reference type, quite similar to a class. Transcribed it looks like this:
public /* delegate */ class PerformCalculation : MulticastDelegate {
public PerformCalculation(object target, IntPtr method) {}
public virtual void Invoke(int x, int y) {}
public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object state) {}
public virtual void EndInvoke(IAsyncResult result) {}
}
I left the implementations of these members empty, they are actually mapped to code in the CLR. The compiler dynamically generates the method signatures, depending on the signature of the delegate declaration. Note the x and y arguments. The JIT compiler helps to get the constructor called, using the += or -= syntax, it knows the memory address of the delegate target method. The compiler automatically generated the target argument value, depending on whether the target method was static or not. The two arguments map to the (Multicast)Delegate.Target and Method properties. The actual base class instance can be either Delegate or MulticastDelegate, depending on how many targets were subscribed.
Lots of secret sauce going on here.
All delegates inherit from the System.Delegate type which hold a Target and Method. More precisely they inherit from System.MultiCastDelegate which inherits from System.Delegate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With