Pull to refresh

Comments 14

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

И лучше определится с heap, хип, куча и писать везде одинаково.

Хорошая статья чтобы освежить память, но с неймингом и правда беда. Правда в последней части лично я бы выразился не "копия структуры не создаётся", а структура боксится 2 раза в 2 разных ссылочных объекта. И я бы добавил довольно очевидные, но полезные для подрастающих разработчиков вещи, что low-level c# это пережёванный компилятором код, поэтому лапша

Action act = (Action) Delegate.Combine((Delegate) new Action((object) cnter, __methodptr(Iteration)), (Delegate) new Action((object) cnter, __methodptr(Iteration)));

На деле оптимизация компилятора над Actionact = cnter.Iteration; + заворачиванием правой части выражения act += cnter.Iteration в Action-делегат и итоговой комбинацией двух получившихся делегатов. Здесь же можно добавить, что любая операция, происходящая между делегатом и методом под капотом всегда приводит к оборачиванию метода экземпляром делегата, включая подписку на event, если только в событии не переопределены аксессоры add/remove.
Ну и просто любопытные вещи в духе myDelegate() полностью эквивалентен myDelegate.Invoke(), с той лишь разницей что во второй вариант можно вставить Null-conditional myDelegate?.Invoke(), про очень полезный паттерн применения IDisposable и комбинации(подписки) делегатов и то, почему он защищает от утечек памяти (статья очень хорошо акцентирует внимание на захвате ссылки на экземпляр объекта), хотя про события я бы в целом добавил, материала не так много, при этом с моего опыта именно через инкапсулирующие event`ы разработчики чаще всего работают с делегатами на практике, ну и всякая вариантность generic-делегатов, хотя это уже довольно общая информация.
В любом случае автору плюсик.

спасибо за комментарии, что решил нужным - учёл. А так как раз собирался комплексом поместить работу с ивентами в отдельную статью, чтобы лучше видеть разницу, что и как где работает\используется

Автору статьи загадка

Func<int> x = () => 1;
x += () => 2;
Console.WriteLine(x());

Какой будет результат, не запуская код?

Без этого статья будет не полной.

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

Ну и, как обычно, про отличающееся поведение замыкания для переменной цикла foreach все забыли.

Да кому нужно изменение поведения в netfx40 15-летней давности... (кроме тех, кто поддерживает такой код).

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

А я не писал про изменение поведения. Я писал про отличие поведения переменных в циклах for и foreach. Вещь совершенно неочевидная.

Ну и на самом деле легаси кода предостаточно. Работал в весьма крупной страховой компании, так там основной софт, на котором крутятся все основные процессы написан на 4 фреймворке. И когда замену этому напишут, совершенно непонятно. И, конечно же, это все приходится поддерживать.

До 3.5 поведение было одинаковым, после изменений в 4.0 стало разным

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

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

try
    {
      while (enumerator.MoveNext())
      {
        Program.<>c__DisplayClass0_0 cDisplayClass00 = new Program.<>c__DisplayClass0_0();
        cDisplayClass00.i = enumerator.Current;
        action = (Action) Delegate.Combine((Delegate) action, (Delegate) new Action((object) cDisplayClass00, __methodptr(<Main>b__0)));
      }
    }
    finally
    {
      enumerator.Dispose();
    }

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

Ну так это должно быть в статье, как мне кажется.

Вприницпе согласен, момент с захватом переменной в цикле (как это в фориче) более подробно разобрал в статье.Спасибо за подсказку с таким неочивидным моментом

Sign up to leave a comment.

Articles