Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a delegate point to?

Tags:

c#

.net

delegates

I have read that a reference type holds the reference to an actual object which may be stored on the managed heap. When a method is "assigned" to a delegate reference variable, to what memory does the reference point to? What does this memory block has to do with the actual function code?

like image 864
blitzkriegz Avatar asked Feb 25 '12 03:02

blitzkriegz


1 Answers

Let's take apart a simple example:

using System;
class Program
{
    delegate bool MyFilter(int x);

    bool IsOdd(int x)
    {
        return x % 2 == 1;
    }

    static void Main()
    {
        MyFilter f = new Program().IsOdd;
        Console.WriteLine(f(5));
    }
}

What does the compiler do? Let's start with this line:

delegate bool MyFilter(int x);

The compiler generates a type that looks somewhat like this:

class MyFilter : MulticastDelegate
{
    public MyFilter(Object thisRef, IntPtr method);
    public bool Invoke(int x);
    // BeginInvoke(), EndInvoke() - Let's ignore those
}    

The type MyFilter has a constructor that accepts two parameters: an IntPtr to the method body to invoke, and an Object on which this method should be invoked. The Invoke() method on the MyFilter type invokes the actual delegate.

Now, let's look at what happens in the Main() method. The compiler will rewrite it somewhat like this:

    static void Main()
    {
        MyFilter f = new MyFilter(new Program(), addressof(Program.IsOdd));
        Console.WriteLine(f.Invoke(5));
    }

Of course, addressof is not an actual C# operator, but you can imagine that it returns the address of the body for the method passed-in. Also, I didn't discuss various other topics related to delegates such as chaining (that's a feature provided by the MulticastDelegate base class), but hopefully I've addressed your question.

To summarize, the delegate reference points to an object that implements an Invoke method that matches the signature of the delegate. The object tracks the pointer to the method that needs to be invoked, and also the target object on which to invoke the method (unless the method is static).

like image 107
Igor ostrovsky Avatar answered Sep 25 '22 02:09

Igor ostrovsky