Как стать автором
Обновить
54
-2.9

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

Отправить сообщение
Будет явно объявлена локальная переменная в вызывающем методе. Если до вызова и инициализации переменной дело может не дойти, то при попытке её использования в небезопасном месте компилятор выдаст ошибку.

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

Польза не совсем очевидна, но здорово помогает писать 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' не является чем-то из рядя вон выходящим.
В альтернативном подходе тоже всё консистентно.
Извините, скажу прямо, для меня это костыльчик.
Да, я могу использовать 'is object' только для проверки

if (GetModel() is object m) WriteLine($"It is model {m}");
else WriteLine("It is null");

Но мне нужен сам тип, чтобы, например, обратиться к переменной 'm.Name'

if (GetModel() is var m) WriteLine($"It is model {m.Name}");
else WriteLine("It is null");
Как же вы всё не поймёте меня… Если мне достаточно проверки на 'null', то я не хочу указывать тип явно и подключать нэймспейс. Просто хочу чтобы компилятор вывел тип (но мне важна эта null-проверка).

if (GetModel() is IModel m) WriteLine($"It is model {m}");
else WriteLine("It is null or not model");

if (GetModel() is var m) WriteLine($"It is model {m}");
else WriteLine("It is null");
Я ж вам говорю про идеальный случай, а не про текущий релиз, который и пытаюсь оспорить.
Как же невозможно? ) Старый добрый if-else да 'is', 'as' в помощь или даже elvis оператор '? :'.

Да. Лучше ввести новое ключевое слово, чем расширять смысл уже имеющихся 'var', 'is'.
Лучше бы ввели новое ключевое слово, а не новый оператор на основе старых.

Информация

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