DEV Community

Bruce Axtens
Bruce Axtens

Posted on

Understanding delegates in C# - did I get it right?

I was astounded recently to have someone from overseas ask for my advice. (Hey, I've got imposter syndrome as bad as anyone.) The young man is studying at Technical University of Chemnitz in Germany. Here's what he said [edited],

I am sharing the code with you. Here in the GiveAction() Method, I am passing the reference of Method1(). Although Method1() is non-static method, still I am able to invoke this method via Action. How is the compiler doing implicit conversion? Could you please share your views on that. As far as I know non-static methods always needs an instance on which these methods are invoked.

This is the code he sent [edited]

    class Program
    {
        int i = 4;
        static void Main(string[] args)
        {
            Program p = new Program();
            Action y1 = p.GiveAction();
            y1();
            y1();
            Console.WriteLine();
        }
        private  Action GiveAction()
        {
            return new Action(Method1);
        }
        public  void Method1()
        {
            this.i++;
        }
    }
Enter fullscreen mode Exit fullscreen mode

This was my response:

I've been messing with Action and Func lately (I've got some articles about it on Dev.to)

I've not seen this thing of instantiating the Program class in its own Main method before. I can readily see that it can be done I just never thought of doing it.

Right,

  • GiveAction and Method1 are both methods of the class called Program.
  • p is pointed to an instance of Program. p therefore now has methods GiveAction and Method1.
  • y1 is given the result of running p's instance of GiveAction which in this case is an Action, a function pointer, to p's Method1 method.
  • y1 is evaluated twice, causing the Action, the function pointer to p's Method1 to be evaluated twice thus incrementing the instance variable of p from 4 to 6.

Actions are a bit like JavaScript anonymous functions. That would appear to be the way in which you're using them here.

This is almost equivalent to

function Program() {
    var i = 4;
    return {
        Main: function () {
        var p = new Program();
            var y1 = p.GiveAction();
            y1();
            y1();
            print(i);
        },
        GiveAction: function () {
            return this.Method1;
        },
        Method1: function () {
            this.i++;
        }
    }
}

debugger;
var P = new Program();
P.Main();
Enter fullscreen mode Exit fullscreen mode

However, the i in this implementation doesn't get incremented, so it's not an exact translation.


Okay, community, is what I wrote correct? And how do I get the JavaScript to behave like the C#?

Latest comments (2)

Collapse
 
peledzohar profile image
Zohar Peled

Both Method1() and GiveAction() are instance method (as apposed to static methods) and therefor there's no problem at all accessing Method1() from GiveAction(). Now, let's take a look at the code and add some comments to explain what's going on:

class Program
{
    // An instance field.
    int i = 4; 

    // The only static method in the class, also, the traditional starting point of c# applications.
    static void Main(string[] args)
    {
        // Set p as a new instance of the Program class.
        Program p = new Program(); 

        // Action y1 is initialized with the result of p.GiveAction() which is p.Method1().
        Action y1 = p.GiveAction(); 

        // This execute p.Method1(), so does the next row.
        y1();
        y1();
        Console.WriteLine();
    }

    // An instance method returning an Action.
    private  Action GiveAction()
    {
        return new Action(Method1);
    }

    // An instance method.
    public  void Method1()
    {
        this.i++;
    }
}
Collapse
 
anjankant profile image
Anjan Kant

Awesome :)