Может ли C# делегировать указатель на метод другого класса / объекта? - PullRequest
1 голос
/ 10 марта 2020

Здесь я буду sh, чтобы получить делегатный указатель на функцию, указать на метод класса, который находится в другом классе (с именем Inner), а затем передать его в функцию stati c, как показано ниже:

public class Inner
{
    public int M = 3;
    public void F() { Console.WriteLine("f"); }
    public void G() { Console.WriteLine("g"); }
}
class Program
{
    public static void Caller(Action a)
    {
        a();
    }
    static void Main(string[] args)
    {
        var i = new Inner();
        var f = i.F;
        var g = i.G;
        f();//error
        g();//error
        Program.Caller(f);
        Console.WriteLine("Hello World!");
    }
}

Я из c / c ++, и в c / c ++ указатель на функцию очень прост, но этот код C# не компилируется. Я гуглил и обнаружил, что почти все объяснения делегатов говорят о делегате, который указывает на метод класса внутри себя.

Мой вопрос: как исправить код, чтобы он работал?

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

Кодирование ответа Себа выделение является причиной проблемы, но на самом деле не объясняет, почему.

Это потому, что i.F является группой методов, а не определением c указатель метода. Например, представьте, что Inner было определено так:

public class Inner
{
    public void F() { Console.WriteLine("f"); }
    public void F(string name) { Console.WriteLine(name); }
}

Какой метод будет ссылаться на i.F? F() или F(string)?

По этой причине вам необходимо явно определить тип переменной или привести указатель:

Action f = i.F;

Или:

var f = (Action)i.F;
1 голос
/ 10 марта 2020

Вы не можете установить группу методов в неявных переменных в C#, поэтому, если вы просто измените 2 var в Action, это будет работать

public class Inner
{
    public int M = 3;
    public void F() { Console.WriteLine("f"); }
    public void G() { Console.WriteLine("g"); }
}
class Program
{
    public static void Caller(Action a)
    {
        a();
    }
    static void Main(string[] args)
    {
        var i = new Inner();
        Action f = i.F;
        Action g = i.G;
        f();
        g();
        Program.Caller(f);
        Console.WriteLine("Hello World!");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...