Re[3]: Что такой анонимный метод(функция)?
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.11.19 06:48
Оценка: 5 (2) +1
Здравствуйте, nt2000, Вы писали:

N>правильно ли я понял: функцию вместе с её телом нельзя передавать в параметре (только её заголовок), а вот если её наименование поменять на секретное наименование, то становится возможным передавать в параметре вместе с заголовком и её тело,даже если оно и не существует нигде ?

Нет, неправильно.
Обычные функции имеют имя, по которому к ним обращаются. У них есть и "заголовок", и тело.
Заголовок в данном случае — это сигнатура, которая описывает, что функция принимает, а что — возвращает.
Сигнатуру саму по себе никуда "передать" нельзя.

Давать функции имя нужно в двух случаях:
1. Когда мы хотим использовать её много раз
2. Когда мы хотим задокументировать её назначение.

Вот простой пример:
public static bool IsEven(int i) => { i % 2 == 0;}

....

var even = from n in numbers where IsEven(n) select n;


Здесь мы определили функцию по имени IsEven. Её сигнатура — Func<int, bool>. Её тело — {return i % 2 == 0;}.

В нашем коде эта функция нужна ровно один раз; поэтому замусоривать ею пространство имён — не очень хорошо.
Поэтому мы можем её никак не называть — можно сконструировать её прямо по месту использования:
var even = from n in numbers where n % 2 == 0 select n;

Здесь плохо видно, где заканчивается where и где начинается функция, поэтому можно задать её чуть более явно (по-прежнему оставив её без имени):
var even = numbers.Where((int n)=>{n % 2 == 0});

Тело вполне себе существует; "секретное наименование" тут неважно — это просто подкапотная реализация семантики, заданной спецификацией.
Просто язык позволяет разделить имя функции и ссылку на неё.
То есть мы можем делать в любом порядке — сначала сконструировать именованную функцию, а потом взять на неё ссылку и передать туда, где ждут ссылку на функцию:
var even = numbers.Where(IsEven); // это функция из первого примера

А можем сначала сконструировать функцию, а потом дать имя ссылке на неё:
Func<int, bool> isEven = (n)=>{n % 2 == 0}); // справа - анонимная функция, слева - именованная переменная типа "делегат"
var even = numbers.Where(isEven);

Особенность тут — в том, что без анонимности любой код обязан быть членом класса. То есть можно писать методы, можно — аксессоры свойств, а вот для "просто кусок кода с параметрами" в хардкорных ОО-языках конструкций нету.

Конструкции типа linq во многом опираются на такие вот простые кирпичики без повторной используемости, заставлять программиста выписывать отдльно все декларации всех участвующих "кусков кода" — оверкилл. Код теряет читаемость.
Вот для её сохранения и приделали анонимные функции в C#.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.