Группы методов (С# In Depth) - Нужна помощь, чтобы лучше понять, что такое группа методов

Итак, я прочитал ряд вопросов StackOverflow, связанных с "что такое группа методов", а также другие интернет-статьи, все они говорят то же самое в нижней строке, что группа методов представляет собой "группу перегруженных методов" ".

Однако, читая Jon Skeet "С# In Depth (второе издание)", он формулирует следующую формулировку относительно группы методов в контексте лямбда-выражений (глава 9.4.1)

Причины изменения: оптимизация общих вызовов методов

Вывод типа происходит в нескольких ситуациях. Мы уже видели, что оно применяется неявно   типизированных массивов, а также требуется, когда вы пытаетесь неявно преобразовать группу методов   к типу делегата. Это может быть особенно запутанным, когда происходит преобразование   когда вы используете группу методов в качестве аргумента для другого метода: с перегрузкой   вызываемого метода и перегрузка методов внутри метода   группы, а также возможность применения общих методов, набор потенциалов   конверсии могут быть огромными ".

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

Может ли кто-нибудь объяснить, что он говорит, возможно здесь?

Спасибо,

Ответ 1

Сценарий, описываемый Джоном, следующий:

int M() {...}
string M<T>(T t) {...}
double M<T>(List<T> t) {...} 
static void M(double d) {...}
... etc ...

void N(Func<int> f) {...}
void N<T>(Action<T> a) {...}
void N<T>(Func<IEnumerable<T>> f) {...}
... etc ...

N(M);

N и M - обе группы методов, содержащие потенциально десятки методов, некоторые из которых могут быть общими. Проблема, поставленная перед компилятором, заключается в "разработке тех методов N и M, которые были разработаны разработчиком, и выработки аргументов типа, если предполагаемый метод является общим".

Чтобы выполнить все это, компилятор должен попробовать все возможные N, а затем выяснить, какой из всех возможных M совместим с типом делегирования формального параметра этой перегрузки N. Он должен отбросить те, которые работа, а затем из всех тех, кто потенциально сотни или тысячи комбинаций ушли, выяснить, какой из них "лучший", если таковой имеется. Это несколько сложная проблема в семантическом анализе.

Ответ 2

Группа методов - это выражение, представляющее множество перегруженных методов, поэтому должно быть очевидно, что он говорит о создании делегата с использованием такого выражения. Например:.


class Foo
{
public static void M() {}
public static void M(int _) {}
}
...
Action a = new Action(Foo.M); // Foo.M is a method group here.

Вы также можете взглянуть на спецификацию С# для получения более подробной информации.

Выражение классифицируется как одно из следующего:
...
• Группа методов, которая представляет собой набор перегруженных методов, полученных в результате поиска элемента (§7.4). Группа методов может иметь связанное выражение экземпляра и связанный список аргументов типа. Когда вызывается метод экземпляра, результатом оценки выражения экземпляра становится экземпляр, представленный этим (§7.6.7). Группа методов разрешена в выражении-вызове (§7.6.5), выражении-делегатете-выражении (§7.6.10.5) и как левая сторона оператора is и может быть неявно преобразована в совместимый тип делегирования (§6.6). В любом другом контексте выражение, классифицированное как группа методов, вызывает ошибку времени компиляции.

Ответ 3

Разве он просто не говорит, что трудно сказать, что вы имеете в виду, когда предоставляете группу методов в качестве аргумента, потому что это может быть любой из методов внутри группы?

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