Search code examples
c#genericsdelegates

c# how to call an Action from generic extension method in another class


I am trying to write a Library of functions to be used by all the classes in my project ( a little unity game ). This question has possibly been asked already but I'm not sure what to search for and haven't found anything yet, so here I am. I want to create a function in a Library that takes in argument a delegate ( or at least, an object of type Action, not sure if that's really called a delegate ) and runs it. The catch is, this Action has to be called by an object of another type and potentially modify it ( meaning it has to be called by the other object ). I'm thinking about using a generic extension method for this. Here is some code I have for now( although this code doesn't work, it should be pretty explicit):

    public static class Library 
{
    public static void doStuffandCallMethod<T>(this T self, Action methodToExecute) {
        //DoStuff
        self.methodToExecute();

    }
    
}

which is my attempt at generalizing this code:

public static void WaitAndDo( Action methodToExecute) {
        //DoSuff();
        methodToExecute();
    }

which works fine. However, the compilator doesn't understand and look for a method called methodToExecute in the class T instead of replacing it by the method described by the parameter (Action) methodToExecute. How am I supposed to do call this Action as the object self, from the class Lib?

Big thanks to those who take the time to thing about it ;)

Edit: Here is a minimal exemple:

public class myObject {
    int number;

    public myObject() {
        number = 0;
    }

    public void method1() {
        Console.WriteLine("Bob is a great guy");
    }
    public void method2() {
        number++;
    }

    public void method3() {
        DoItForMe<myObject>(method2);
    }
}

public class Lib {
    public static void DoItForMe<T>(this T self, Action methodToExecute) {
        self.methodtoExecute();
    }
}

Then from the main:

myObject bob = new myObject();
bob.method3();
Console.WriteLine("bob's number is" + bob.number);

should give the output

bob's number is 1


Solution

  • methodToExecute must be called without self, because this method is a parameter and not a method of self.

    public static class Library
    {
        public static void DoStuffandCallMethod<T>(this T self, Action methodToExecute)
        {
            //DoStuff
            methodToExecute();
        }
    }
    

    DoStuffandCallMethod is an extension method of your instance, you can call it with this:

    public class MyObject
    {
        private int number;
        public int Number => number;   // if you want to access from outside.
        // ...
    
        public void Method2()
        {
            number++;
        }
    
        public void Method3()
        {
            this.DoStuffandCallMethod(Method2);
        }
    }
    

    You are extending every type. You can call DoStuffandCallMethod from an int, ... I have the feeling that interfaces are a better approach than extension methods for your problem.