Хотите меня в чём-то переубедить, напишите-ка простенький текстовый редактор с аналогичным функционалом. И не забудьте про полное сохранение логического и визуального состояния при перезапуске приложения…
А потом сравните количество и читаемость получившегося кода. Получится лучше — поделитесь с сообществом своими наработками и видением. )
Я воспринимаю это иначе. В любой сфере есть этапы становления и развития, можно досчить определённого уровня, остановиться на нём и чувствовать себя вполне счастливым человеком. А можно активно искать и пробовать в данном направлении что-то новое дальше и дальше, изобретать, фантазировать… Понятно, что такой путь не для всех, но мне он близок. А вы лучше меня знаете, что для вас ближе. :)
Это пишет человек, которому только что было все равно на четырехкратное изменение?
Для вас пишу, ведь это вы так волнуетесь о производительности. Мне достаточно и того факта, что методы-расширения по порядку величин сопоставимы с нативной реализацией. А в 4 или в 1.2 раза отличие для меня не критично, это не в 100 раз и даже не в 10.
(x as T) ?? fallback. Только вы в вашей перегрузке делаете сначала is, а потом каст, так что ни о какой производительности речи и вовсе нет.
Если честно, я не сравнивал производительность именно этого метода с нативной реализацией (да и нативная реализация не поддерживает fallbackValue), но не думаю, что различия будут более чем в десятки раз. Если вы исследуете декомпиляции нативного PM, то увидите, что в разных сценариях он раскладывается в конструкции анологичные перегрузкам метода Is.
… а они более обобщенные? В них уже можно делать паттерн-матчинг? Они взаимозаменяемы с switch...case с идентичным синтаксисом?
Уже можно делать много интересных вещей, просмотрите примеры кода, связанные с Matching.
Затем, что завтра MS возьмет и сделает оптимизацию для этого синтаксического сахара, благо это тривиально. А ваши методы где были, там и останутся.
Почему раньше не сделали? Конечно, там умные люди работают, но вся система в целом иногда выдаёт странные и спорные решения. Поэтому не стоит слепо доверять даже авторитетам, а лучше всё переосмысливать самому.
Да, программирование с неизменяемым состояние имеет свои плюсы, но и свою ограниченную область применения. Для интерфесной логики, которой я по большей части и занимаюсь, этот подход плохо применим. Поэтому не стоит слепо предоваться модным веяниям и тенденциям.
«Видимого размера» — это лишь вершина айсберга, намного важнее, что привносит определённая структура кода в язык, к каким решениям неявно поддталкивает программистов.
Конечно, было бы здорово получить синтаксический сахар на нативном уровне вроде
но это вопросы к разработчикая языка. Я вносил подобные предложения, но дизайнеры уже приняли ряд весьма неоднозначных реший, первое из которых уже в релизе
IModel GetModel() => ...
/* true|false */
GetModel() is IModel m
/* always true */
GetModel() is var m
Далее предполагаются
/* true|false */
GetModel() is {} m // null check
/* true|false */
GetModel() is {Name is {} s, City is var c} m
не знаю, как для вас, но для меня более очевидны такие формы
/* true|false */
GetModel().Is(out var m) // null check
/* true|false */
GetModel().Is(out var m) && m.Check
(
m.Name.Is(out var s), // null check
m.City.To(out var c).Put(true)
).All(true)
Если перефразировать ваше утверждение в терминах программирования, учитывая порядок величин, то получится что-то вроде
"-Сколько у Вас стоит капля водки?
-Нисколько.
-Отлично! Накапайте цистерну!
-Без проблем! Начинайте капать..."
Да и если здраво подойти к вопросу, то
"-Сколько у Вас стоит капля водки?
-Нисколько.
-Отлично! Накапайте стакан!
-Стакан стоит столько-то центов..."
Знаете, ваша позиция напоминает мне такую: «Эти интегралы слишком сложные, нужно приложить усилия, чтобы научиться их читать и понимать, лучше я буду пользоваться школьной математикой». )
Откроется диалог сохранения файлов, а при нажатии на «Ок» вызовется «File.WriteAllText». Если документ будет пустой, то возникнет и обработается исключение ArgumentNullException «contents is empty», в ином случае сохранится, если других исключений не будет.
Ошибки (исключения) не игнорируются, вы можете в этом убедиться сами, запустив приложение.
В первую очередь я отталкиваюсь от логики самой программы, сейчас она функционирует отлично.
Главной вью-модели вообще ни к чему знать об исключениях, возникающих в работе докуметов, там произойти может, что угодно: нет доступа к файлу, формат не тот… Пускай документы сами разбираются, что с этим делать. Задача руководителя лишь создавать их и закрывать, когда нужно, попутно уведомляя о загрузке, закрытии и сохранении.
Все документы реализуют следующий интерфейс (ADocument) доступный для использования в CoreViewModel
public abstract Task<bool> Load();
public abstract Task<bool> Save();
public abstract Task<bool> SaveAs();
public abstract Task<bool> Close();
Подразумевается, что в случае успешного выполнения возвращается true, иначе false.
Когда основная вью-модель вызывает у дочерней один из этих методов, то это выглядит, словно руководитель выдаёт подчинённому команду что-то сделать, ставит задачу.
Это не забота руководителя, каким образом подчинённый будет выполнять задание и обрабатывать возникающие трудности (исключения), важен лишь конечный результат и то, что руководитель выполнил свою работу по постановке задачи. Классическое разделение ответственности.
Ох, не знаю, какой у вас проект, но обычно никто не держит в памяти по сто тысяч объектов за редкими исключениями. В интерпрайз-решениях, как правило, используют виртуализацию на уровне данных и/или визуального интерфейса.
То, о чём вы говорите, это сценарий для высоконагруженного сервера, кэширующего данные в памяти, или же очень специфического клиента. А для исключений нужны и исключительные решения.
Поэтому не вижу смысла отказываться от паттерна общего назначения, из-за каких-то маловероятных падений производительноти. Если вдруг начнёт что-то ощутимо замедляться из-за вызовов 'With', то не вижу проблемы их убрать, благо, код не потребует огромной реструктуризации.
Раз уж язык позволяет стандартными средствами написать 'i is 0', то почему бы и нет? Мне, например, больше нравится писать '==' в контексте арифметических выражений, а в логических использовать 'is', хотя они и взаимозаменяемы в некоторых случаях.
И да, интуитивно я предполагаю, что компилятор умный и развернёт 'i is 0' в 'i == 0', но он поступает иначе. Конечно, 20% не такой уж большой выигрыш в производительности, но уже ощутимый, и, стоит отметить, методы-расширения поддерживают не только константные выражения.
Кроме того, следующая перегрузка позволяет указывать 'fallbackValue', что позволяет писать более гибкую логику
public static TX Put<T, TX>(this T o, TX x) => x;
public static bool Is<T>(this object o,
out T x, T fallbackValue = default(T)) =>
(x = (o is T).To(out var b) ? (T) o : fallbackValue).Put(b);
if (model.Is(out AnyModel m, AnyModel.Default))
Console.WriteLine($"Custom AnyModel {m}");
else Console.WriteLine($"Default AnyModel {m}");
Поэтому возникает закономерный вопрос, раз методы-расширения более обобщённые и не уступают (а иногда и выигрывают) по производительнотсти, то зачем мне использовать встроенный, но весьма ограниченный синтаксический сахар?
Ошибки загрузки из файла обрабатываются в самих дочерних вью-моделях.
На момет окончания метода 'CoreViewModel.Expose' важно выполнить лишь Expose у коллекции документов, а загрузкой данных из файла заведует сам документ.
Как говорится: «Любое категоричное суждение ошибочно, даже это». Поэтому не стоит воспринимать мои слова как абсолютную истину :)
Здорово, что вы критикуете и обдумываете аргументы, не принимая их сразу на веру, ведь я тоже могу ошибаться, заблуждаться и быть слишком субъективным.
А потом сравните количество и читаемость получившегося кода. Получится лучше — поделитесь с сообществом своими наработками и видением. )
Что-то наподобие инициализационного блока с дополнительным префиксом и доступом к контексту через '.'
Для вас пишу, ведь это вы так волнуетесь о производительности. Мне достаточно и того факта, что методы-расширения по порядку величин сопоставимы с нативной реализацией. А в 4 или в 1.2 раза отличие для меня не критично, это не в 100 раз и даже не в 10.
Если честно, я не сравнивал производительность именно этого метода с нативной реализацией (да и нативная реализация не поддерживает fallbackValue), но не думаю, что различия будут более чем в десятки раз. Если вы исследуете декомпиляции нативного PM, то увидите, что в разных сценариях он раскладывается в конструкции анологичные перегрузкам метода Is.
Уже можно делать много интересных вещей, просмотрите примеры кода, связанные с Matching.
Почему раньше не сделали? Конечно, там умные люди работают, но вся система в целом иногда выдаёт странные и спорные решения. Поэтому не стоит слепо доверять даже авторитетам, а лучше всё переосмысливать самому.
Конечно, было бы здорово получить синтаксический сахар на нативном уровне вроде
но это вопросы к разработчикая языка. Я вносил подобные предложения, но дизайнеры уже приняли ряд весьма неоднозначных реший, первое из которых уже в релизе
Далее предполагаются
не знаю, как для вас, но для меня более очевидны такие формы
"-Сколько у Вас стоит капля водки?
-Нисколько.
-Отлично! Накапайте цистерну!
-Без проблем! Начинайте капать..."
Да и если здраво подойти к вопросу, то
"-Сколько у Вас стоит капля водки?
-Нисколько.
-Отлично! Накапайте стакан!
-Стакан стоит столько-то центов..."
:)
Знаете, ваша позиция напоминает мне такую: «Эти интегралы слишком сложные, нужно приложить усилия, чтобы научиться их читать и понимать, лучше я буду пользоваться школьной математикой». )
В первую очередь я отталкиваюсь от логики самой программы, сейчас она функционирует отлично.
Главной вью-модели вообще ни к чему знать об исключениях, возникающих в работе докуметов, там произойти может, что угодно: нет доступа к файлу, формат не тот… Пускай документы сами разбираются, что с этим делать. Задача руководителя лишь создавать их и закрывать, когда нужно, попутно уведомляя о загрузке, закрытии и сохранении.
Я, например, точно знаю, что в моих текущих проектах такого не придвидится, поэтому для себя никаких причин отказываться от паттерна не вижу.
По крайней мере, можно его использовать в задачах, где свехвысокая производительность не критична.
Подразумевается, что в случае успешного выполнения возвращается true, иначе false.
Когда основная вью-модель вызывает у дочерней один из этих методов, то это выглядит, словно руководитель выдаёт подчинённому команду что-то сделать, ставит задачу.
Это не забота руководителя, каким образом подчинённый будет выполнять задание и обрабатывать возникающие трудности (исключения), важен лишь конечный результат и то, что руководитель выполнил свою работу по постановке задачи. Классическое разделение ответственности.
То, о чём вы говорите, это сценарий для высоконагруженного сервера, кэширующего данные в памяти, или же очень специфического клиента. А для исключений нужны и исключительные решения.
Поэтому не вижу смысла отказываться от паттерна общего назначения, из-за каких-то маловероятных падений производительноти. Если вдруг начнёт что-то ощутимо замедляться из-за вызовов 'With', то не вижу проблемы их убрать, благо, код не потребует огромной реструктуризации.
И да, интуитивно я предполагаю, что компилятор умный и развернёт 'i is 0' в 'i == 0', но он поступает иначе. Конечно, 20% не такой уж большой выигрыш в производительности, но уже ощутимый, и, стоит отметить, методы-расширения поддерживают не только константные выражения.
Кроме того, следующая перегрузка позволяет указывать 'fallbackValue', что позволяет писать более гибкую логику
Поэтому возникает закономерный вопрос, раз методы-расширения более обобщённые и не уступают (а иногда и выигрывают) по производительнотсти, то зачем мне использовать встроенный, но весьма ограниченный синтаксический сахар?
На момет окончания метода 'CoreViewModel.Expose' важно выполнить лишь Expose у коллекции документов, а загрузкой данных из файла заведует сам документ.
Здорово, что вы критикуете и обдумываете аргументы, не принимая их сразу на веру, ведь я тоже могу ошибаться, заблуждаться и быть слишком субъективным.