Обновить
58

Пользователь

51
Подписчики
Отправить сообщение
Ваш выбор и ваше дело.

Для меня видимость структуризации, читаемость и выразительность — очень близкие в данном случае понятия.

Но особенно меня цепляет глобальная симметричность и математическая красота подхода в плане обобщений. Это трудно объяснить и сразу прочувствовать, но мне самому теперь нравится, хотя поначалу были сомнения в его целесообразности.
Спасибо, буду называть правильно.
С точки зрения метода 'With' есть контекст, который будет обратно возвращён в цепочку вызовов.

Да, одинаковые названия переменных будут конфликтовать, но есть возможность их повторного переиспользования.
Он и не должен что-то значить — это лишь синтаксический сахар для структуризации кода.
Я не силён в терминологии, но подразумеваю такие методы, которые не содержат скобок и декларируются наподобие лямбда-выражений

IModel GetModel() => new AnyModel();
Локальная переменная в методе
void Test()
{
    GetPoint().To(out var p).With
    (
        p.X.To(out var x),
        p.Y.To(out var y),
    ).DoSomething();
    
    Console.WriteLine($"{x}, {y}");
}
Будет явно объявлена локальная переменная в вызывающем методе. Если до вызова и инициализации переменной дело может не дойти, то при попытке её использования в небезопасном месте компилятор выдаст ошибку.

Так что в скомпилированном коде переменная будет точно проинииализирована, если не произойдёт исключений.
В подавляющем большинстве практических задач лишний вызов почти пустого метода никаких существенных накладок не вносит, поэтому подход довольно безопасный. И да, можно вставлять и «левые» выражения, иногда такая возможность весьма к месту (но если разрабтчик решит использовать совсем уж посторонние выражения, слабо связанные с логикой метода, то это лишь его ответственность).

Польза не совсем очевидна, но здорово помогает писать bodied методы в одну цепочку.
Работает по аналогии с инициализационными блоками
new Person
{
    Name = "AnyName"
}.DoSomethig();

раскладывается компилятором в
var tmpContext = new Person();
tmpContext.Name = "AnyName"
tmpContext.DoSomething();

В случае с 'With' мы декларируем контекст явно
new Person().To(out var p).With
(
    p.Name = "AnyName"
).DoSomething();

Единственное отличие состоит в дополнительном вызове метода 'With' для которого подготавливаются переменные в стеке. Декомпиляцию можно посмотреть тут.

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

Для сравнения вVisualBasic есть оператор 'With', а доступ к временному контексту выполняется через '.', что-то пожее на следующий псевдо-код
new Person().With
{
    .Name = "AnyName",
    .ToString() to var stringView
}.DoSomethig();


В любом случае, дело вкуса. Мне лично 'With' паттерн особенно нравится тем, что очень помогает писать bodied методы.
называйте, как захотите.

лично моё мнение, можно было бы реализовать pattern matching в C# более чисто и очевидно, чем это уже сделано сейчас.
Вообще-то это вполне себе рабочая модель, которая прекрасно иллюстирирует, как работает матчинг по значениям и по типам, и в чём между ними разница. Конечно, модель не нужно понимать буквально, поскольку она реализована в жёстких рамках языка (C# не позволяет расширять синтаксис), но матчит значения и типы она исправно.
И почему так должно быть? Как вы понимаете доводы LDM?
Вот вы можете мне объяснить, почему способ объявления переменной оказывает прямой эффект на поведение pattern matching? Я думаю, что без этого вполне можно обойтись, как обходятся F# и Scala, например.

Вот вполне рабочая модель подобного подхода
github.com/dotnet/csharplang/issues/1196#issuecomment-355054947
Проблема даже не столько в том, что есть сейчас, а в том, к чему это может привести в будущем. А именно новый способ декларации переменных в языке '{ } m' к уже имеющимся 'IModel m' и 'var m'.
Именно. Новый способ объявления переменной в языке.
Там лишь несколько человек напрямую из LDT.

Раз вас всё устраивает, то добавят вам ещё один способ объявления переменных для ещё большей «консистентности»
'{ } m'.
Эм… Объявление операторами 'out' + 'var' переменной, даже если они как бы и не выполняются… Не знаю, как вам, а мне нравится.

IModel GetModel() => null;
GetModel()?.To(out var m);
m = new AnyModel();
Альтернативный подход здесь
github.com/dotnet/csharplang/issues/1224
и отчасти тут (детали в самой дискуссии)
github.com/dotnet/csharplang/issues/1196
Справедливости ради отмечу, что опрераторы 'out' + 'var' могут объявить переменную x, даже если они очевидным образом не выполняются.
new Point() {  X = GetPont()?.Unwrap(out var x, out var y) }
new Point() {  X = GetPont()? { X to var x, Y to var y) }

Поэтому дополнительная инициализация переменной дефолтным значением с помощью 'to'+'var' не является чем-то из рядя вон выходящим.
В альтернативном подходе тоже всё консистентно.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность