Я, конечно, понимаю, что компилятору тяжело разобрать подобную ситуацию (и можно придумать её усложнения), но 'x', 'y' в данном конкретном случае будут однозначно проинициализированы в момент использования.
int? x,y;
var p = GetPoint();
if (p != null)
p.Unwrap(out x, out y);
if (p == null) WriteLine("It is null");
else WriteLine($"X={x}; Y={y}");
Мне пока никто не привёл примера кода, который невозможно было бы переписать методами-расширениями. Вот вы такой придумайте, и я сразу скажу: «Да, я не прав, ничего не понял в паттерн-матчинге и другим предлагал чёрти что».
Пока что для меня ваш паттерн матчинг ради паттерн матчинга. Мой «не паттерн-матчинг» — синтаксический сахар ради лаконичности кода.
Многие проблемы прекрасно решаются и без PM с помощью extension methods. Это же не повод отменять PM, но и не повод не делать такую фичу. Так почему бы не скомбинировать оба подхода, если это возможно сделать?
Вообще-то метод 'Unwrap' вызовется, если 'GetPoint' вернёт не 'null' и переменные 'x', 'y' получат свои значения. Просто контроль ветвлений не может сейчас этого понимать. Против NRE я совершенно ничего не имею, пример ниже прекрасно cкомпилируется и cгенерирует исключение в случае 'null'.
//var p = GetPoint() { X to var x, Y to var y);
var p = GetPoint().Unwrap(out var x, out var y);
if (p == null) WriteLine("It is null");
else WriteLine($"X={x}; Y={y}");
Есть маленькая разница между свойствами класса и переменными метода. Куча и стек.
Да, разница есть, но она не столь существенна с практической точки зрения, от лишнего присваивания производительность метода не просядет.
Также не идёт речи про изменение поведения 'out', идёт речь про оператор 'to', который инициализирует переменную дефолтным значением, если для неё оказалось недоступным другое.
Вас это не устраивает, но меня вполне. Тот синтаксис, который можно будет получить, благодаря этому допущению, выглядит для меня в разы более привлекательным, чем лишнее присваивание.
Уж не обобщайте так, я не рассказываю про тот PM, каким вы его привыкли видеть. Если бы я знал его раньше, таким же и как вы, то, вероятно, принял бы моногие нестыковки как данность. Именно свежий взгляд позволяет увидеть всё с другой стороны.
На C# я пишу довольно много и доводилось делать непростые вещи… Если вам очень интересно, то можете полистать примеры кода.
Моя главные ориентиры в программировании — красота, лаконичность и простота. Основные мерила — обобщённость и количество строк. Из двух одинаково обобщённых решений для меня наиболее привлекательно то, в котором меньше строк.
Предлагаемая стандартная реализация PM будет мешать мне писать bodied-методы и решать некоторые задачи меньшим числом строк кода, поэтому у меня есть большое желание её переработать для большей лаконичности.
Конечно, прекрасно понимаю, что есть некоторые breaking changes, поэтому шансы что-то изменить призрачны, но, по крайней мере, я пробую свои мысли кому-то донести.
//var p = GetPoint()? { X to var x, Y to var y };
var p = GetPoint()?.Unwrap(out var x, out var y);
if (p == null) WriteLine("It is null");
else WriteLine($"X={x}; Y={y}");
Сейчас такой код не компилируется с ошибками
[CS0165] Use of unassigned local variable 'x'
[CS0165] Use of unassigned local variable 'y'
Хотя если 'p != null', обе переменных будут успешно проинициализированны и можно безопасно их использовать. То есть в теории здесь можно добавить контроль ветвлений для решения проблемы компиляции.
Либо же достаточно проинициализировать переменные дефолтными значениями. Если программисту будет важно, откуда пришли эти значения, то он сможет разобраться, используя значение переменной 'p'. Ведь если мы объявляем переменную в классе без явной инициализации, то она инициализируется дефолтным значением и компилятор не ругается, что мы её не проинициализировали чем-то определённым.
class AnyClass
{
private int _anyVariable0;
private string _name;
public Print() => Console.WriteLine(_name);
}
Хорошо, можно считать, что у меня тоже шаблонное мышление C# разработчика, поэтому я защищаю прежде всего видение с классической стороны и предлагаю синтаксис, который гармонично вписывается и развивает язык, открывая путь новым функциям.
Это ваше право так считать, что код не должен ломаться. Однако лично я согласен на некоторые breaking changes в мажорных релизах, которые помогут мне сделать язык более красивым и выразительным.
Предлагайте, создавайте новую дискуссию на гитхабе, обсуждайте… Если честно, я только представляю, как работает конвейер в микропроцессоре, но про такую функцию в языках программирования не слышал, поэтому сейчас не могу оценить, насколько она мне могла бы быть интересна и полезна.
'var' используется в польностью классическом понимании.
Вы мыслите шаблонно, PM так работает в других языках. Но что если предположить, что в C# может быть ещё лучше? Просто изучите новое предложение по улучшению синтаксиса языка. Вы можете найти в нём противоречия?
Хочу вас обрадовать. Ваш релизный код не сломается в контексте C# 8, он может перестать работать только для nullable value types (bool?, int?, etc.).
Суть в другом — в расширении значения 'var' и 'is var', без этого можно обойтись.
Пока что для меня ваш паттерн матчинг ради паттерн матчинга. Мой «не паттерн-матчинг» — синтаксический сахар ради лаконичности кода.
Многие проблемы прекрасно решаются и без PM с помощью extension methods. Это же не повод отменять PM, но и не повод не делать такую фичу. Так почему бы не скомбинировать оба подхода, если это возможно сделать?
Увы, вероятно, она закроет для меня такой синтаксис
Да, разница есть, но она не столь существенна с практической точки зрения, от лишнего присваивания производительность метода не просядет.
Также не идёт речи про изменение поведения 'out', идёт речь про оператор 'to', который инициализирует переменную дефолтным значением, если для неё оказалось недоступным другое.
Вас это не устраивает, но меня вполне. Тот синтаксис, который можно будет получить, благодаря этому допущению, выглядит для меня в разы более привлекательным, чем лишнее присваивание.
На C# я пишу довольно много и доводилось делать непростые вещи… Если вам очень интересно, то можете полистать примеры кода.
Моя главные ориентиры в программировании — красота, лаконичность и простота. Основные мерила — обобщённость и количество строк. Из двух одинаково обобщённых решений для меня наиболее привлекательно то, в котором меньше строк.
Предлагаемая стандартная реализация PM будет мешать мне писать bodied-методы и решать некоторые задачи меньшим числом строк кода, поэтому у меня есть большое желание её переработать для большей лаконичности.
Конечно, прекрасно понимаю, что есть некоторые breaking changes, поэтому шансы что-то изменить призрачны, но, по крайней мере, я пробую свои мысли кому-то донести.
Сейчас такой код не компилируется с ошибками
[CS0165] Use of unassigned local variable 'x'
[CS0165] Use of unassigned local variable 'y'
Хотя если 'p != null', обе переменных будут успешно проинициализированны и можно безопасно их использовать. То есть в теории здесь можно добавить контроль ветвлений для решения проблемы компиляции.
Либо же достаточно проинициализировать переменные дефолтными значениями. Если программисту будет важно, откуда пришли эти значения, то он сможет разобраться, используя значение переменной 'p'. Ведь если мы объявляем переменную в классе без явной инициализации, то она инициализируется дефолтным значением и компилятор не ругается, что мы её не проинициализировали чем-то определённым.
Это ваше право так считать, что код не должен ломаться. Однако лично я согласен на некоторые breaking changes в мажорных релизах, которые помогут мне сделать язык более красивым и выразительным.
Здесь предложено одно из решений проблемы, потенциально возможно и другое — усложнение логики компилятора (контроль null-ветвлений кода).
Однако с другой стороны — объявления переменных в классах также эквивалентны записи
поэтому такое решение тоже возможно.
Вы меня слышите? На 'null' проверяет оператор 'is', а не 'var'.
Не понимаю, что здесь нелогичного? Функция возвращает nullable string, компилятор выводит для переменной foo соответствующий тип. Эквивалентно
'var' используется в польностью классическом понимании.
Вы мыслите шаблонно, PM так работает в других языках. Но что если предположить, что в C# может быть ещё лучше? Просто изучите новое предложение по улучшению синтаксиса языка. Вы можете найти в нём противоречия?
Хочу вас обрадовать. Ваш релизный код не сломается в контексте C# 8, он может перестать работать только для nullable value types (bool?, int?, etc.).