Pull to refresh
56
0

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

Send message
Хотите меня в чём-то переубедить, напишите-ка простенький текстовый редактор с аналогичным функционалом. И не забудьте про полное сохранение логического и визуального состояния при перезапуске приложения…

А потом сравните количество и читаемость получившегося кода. Получится лучше — поделитесь с сообществом своими наработками и видением. )
Не смущает, Load можно вызывать в любой момент, даже в процессе редактирования документа, чтобы заново перезагрузить данные из файла.
Вот только в этот момент непонятно, что такое With с точки зрения синтаксиса.

Что-то наподобие инициализационного блока с дополнительным префиксом и доступом к контексту через '.'
Пользозуйтесь обычным, я же вас не ни к чему не склоняю, только даю выбор.
Я воспринимаю это иначе. В любой сфере есть этапы становления и развития, можно досчить определённого уровня, остановиться на нём и чувствовать себя вполне счастливым человеком. А можно активно искать и пробовать в данном направлении что-то новое дальше и дальше, изобретать, фантазировать… Понятно, что такой путь не для всех, но мне он близок. А вы лучше меня знаете, что для вас ближе. :)
Это пишет человек, которому только что было все равно на четырехкратное изменение?

Для вас пишу, ведь это вы так волнуетесь о производительности. Мне достаточно и того факта, что методы-расширения по порядку величин сопоставимы с нативной реализацией. А в 4 или в 1.2 раза отличие для меня не критично, это не в 100 раз и даже не в 10.

(x as T) ?? fallback. Только вы в вашей перегрузке делаете сначала is, а потом каст, так что ни о какой производительности речи и вовсе нет.

Если честно, я не сравнивал производительность именно этого метода с нативной реализацией (да и нативная реализация не поддерживает fallbackValue), но не думаю, что различия будут более чем в десятки раз. Если вы исследуете декомпиляции нативного PM, то увидите, что в разных сценариях он раскладывается в конструкции анологичные перегрузкам метода Is.

… а они более обобщенные? В них уже можно делать паттерн-матчинг? Они взаимозаменяемы с switch...case с идентичным синтаксисом?

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

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

Почему раньше не сделали? Конечно, там умные люди работают, но вся система в целом иногда выдаёт странные и спорные решения. Поэтому не стоит слепо доверять даже авторитетам, а лучше всё переосмысливать самому.
Да, программирование с неизменяемым состояние имеет свои плюсы, но и свою ограниченную область применения. Для интерфесной логики, которой я по большей части и занимаюсь, этот подход плохо применим. Поэтому не стоит слепо предоваться модным веяниям и тенденциям.
«Видимого размера» — это лишь вершина айсберга, намного важнее, что привносит определённая структура кода в язык, к каким решениям неявно поддталкивает программистов.

Конечно, было бы здорово получить синтаксический сахар на нативном уровне вроде
GetPerson()?.With
{
    .FirstName = "Иван",
    .LastName = "Пупкин"
}.DoSomething();

но это вопросы к разработчикая языка. Я вносил подобные предложения, но дизайнеры уже приняли ряд весьма неоднозначных реший, первое из которых уже в релизе
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», в ином случае сохранится, если других исключений не будет.
Ошибки (исключения) не игнорируются, вы можете в этом убедиться сами, запустив приложение.

В первую очередь я отталкиваюсь от логики самой программы, сейчас она функционирует отлично.

Главной вью-модели вообще ни к чему знать об исключениях, возникающих в работе докуметов, там произойти может, что угодно: нет доступа к файлу, формат не тот… Пускай документы сами разбираются, что с этим делать. Задача руководителя лишь создавать их и закрывать, когда нужно, попутно уведомляя о загрузке, закрытии и сохранении.
Если вы заранее предполагаете, что у вас в проекте может возникнуть такая ситуация, то просто не используйте метод With.

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

По крайней мере, можно его использовать в задачах, где свехвысокая производительность не критична.
Все документы реализуют следующий интерфейс (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 у коллекции документов, а загрузкой данных из файла заведует сам документ.
Как говорится: «Любое категоричное суждение ошибочно, даже это». Поэтому не стоит воспринимать мои слова как абсолютную истину :)

Здорово, что вы критикуете и обдумываете аргументы, не принимая их сразу на веру, ведь я тоже могу ошибаться, заблуждаться и быть слишком субъективным.

Information

Rating
Does not participate
Registered
Activity