Что делает имя метода эквивалентным делегату действия? - PullRequest
5 голосов
/ 12 ноября 2011

Я просто экспериментировал и получил следующий фрагмент:

public static class Flow {
    public static void Sequence(params Action[] steps) {
        foreach (var step in steps)
            step();
    }
}
void Main() {
    Flow.Sequence(() => F1(), () => F2());
    Flow.Sequence(F1, F2); // <-- what makes this equiv to the line above?

}
void F1() { }
void F2() { }

Я не осознавал, что одно только имя метода совпадает с действием.

Что делаетэто так?

Ответы [ 3 ]

7 голосов
/ 12 ноября 2011

В C # делегаты - не более чем указатели на методы .Они могут указывать на существующие методы в классе или на независимые анонимные объекты-делегаты.

Этот абзац из приведенной выше ссылки должен объяснить, что происходит в вашем коде:

Любой метод, который соответствуетподпись делегата, состоящая из возвращаемого типа и параметров, может быть назначена делегату.Это позволяет программно изменять вызовы методов, а также вставлять новый код в существующие классы.Если вам известна подпись делегата, вы можете назначить собственный делегированный метод.

То есть при разрешении типов делегатов учитываются их подписи, а не их имена.

В вашем случае ваши F1() и F2() методы, не принимающие параметров и не возвращающие ничего, имеют совпадающие подписи с безпараметрическим Action делегатом :

public delegate void Action();

Следовательно,они неявно преобразуются в Action.

Если вы попытаетесь передать метод с другим типом возвращаемого значения или хотя бы одним параметром, вы получите ошибку времени компиляции, поскольку она не будет соответствоватьAction подпись.

3 голосов
/ 12 ноября 2011

По сути, это то, что происходит на заднем плане:

void Main() 
{    
    Flow.Sequence(new Action(delegate(){ F1(); }), new Action(delegate(){ F2(); }));    
    Flow.Sequence(new Action(F1), new Action(F2)); 
}

Они не ТОЧНО эквивалентны, но они очень близки. Они будут отображать те же результаты во время выполнения, с той лишь разницей, что аргументы в первом вызове Sequence будут Action, который вызывает анонимный метод, который затем вызывает статические методы F1 и F2; вторым вызовом последовательности будет действие, которое вызывает статические методы F1 и F2.

Надеюсь, это поможет.

0 голосов
/ 12 ноября 2011

Компилятор использует неявное преобразование из группы методов в делегат совместимого типа (в данном случае это метод, возвращающий пустую строку без аргументов), имена методов здесь не имеют отношения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...