Групповые делегаты

461
29 декабря 2016, 06:03
Action a1 = () => Console.Write(1); 
Action a2 = () => Console.Write(2); 
Action a3 = () => Console.Write(3); 
((a1 + a2 + a3) - (a1 + a2))(); 
((a1 + a2 + a3) - (a1 + a3))();

Увидел данный пример и стало интересно. Как в данном случае отрабатывает удаление делегата. Что происходит при (a1 + a2) и (a1 + a3), и почему первый вариант удаляет как надо а второй не срабатывает вовсе?

Answer 1

Пускай a1 + a2 + a3 превращается в делегат, который условно обозначим [a1, a2, a3], a1 + a2 -- [a1, a2], a1 + a3 -- [a1, a3].

При вычитании в [a1, a2, a3] ищется кусок подряд, который равен вычитаемому. Для [a1, a2] такой кусок найдётся, начиная с индекса 0, а для [a1, a3] -- нет. Поэтому при вычитании [a1, a2, a3] - [a1, a2] получается [a3], а при вычитании [a1, a2, a3] - [a1, a3] подходящий кусок не находится, и вычитание не происходит.

Смысл такого правила в том, что если уж делегат получен сложением одного списка с другими, то это первый список будет найден в суммарном делегате как подсписок. Поэтому вычитание в этом случае имеет смысл.

Цитата из стандарта, параграф 7.8.5:

... Результатом является новый список вызова, состоящий из списка первого операнда с удалёнными элементами списка второго операнда, при условии, что второй список является непрерывным (нетривиальным) подсписком первого [...] В противном случае, результатом является вычитаемое.

READ ALSO
Преобразование Double к DateTime

Преобразование Double к DateTime

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

779
Как скачать всё, что находится в div?

Как скачать всё, что находится в div?

ИСПОЛЬЗУЕТСЯ: WebDriver, С#

497
Не открывает папку Process.Start()

Не открывает папку Process.Start()

Не открывает папкуКак будто ее на существует

484
Конвертация изображения png в jpg C#

Конвертация изображения png в jpg C#

ЗдравствуйтеЕсть изображение в формате png

540