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

Комментарии 29

Спасибо за очень краткий пересказ блогов Microsoft.
И, как же слух режет… :) Интересно, сколько ещё людей слышат букву «Т» в слове feature?
По поводу DTO — посмотрите в сторону AllowNull, DisallowNull, MaybeNull, NotNull и прочих атрибутов. Если я правильно понимаю проблему — это может помочь?
Попробовал, к сожалению, не помогло:( Но спасибо за идею
Copy-paste в switch по идее можно как минимум уменьшить вынеся логику в отдельный метод. Во всяком случае я пока так сделал. Правда это немного портит читаемость кода.

Ну и будем надеяться что это поправят.

.NET очевидно это тупикновая технология, пока были популярны десктопные приложения под Windows она еще как то жила. А сейчас во времена web и смартфонов, учитывая что Windows Phone уже мертвая а главная фишка CLR- кроссплатформенность оказалась не по зубам Микрософту, только неопытный студент захочет использовать тот же .Net Core в продакшене...

Простите коллеги, я не мог не пропустить этот коммент, он прекрасен:)
НЛО прилетело и опубликовало эту надпись здесь

Я бы не был столь категоричен учитывая сколько денег и усилий Microsoft сейчас вбухивает в .Net и конкретно в попытки сделать его кроссплатформеным. У меня вообще такое ощущение что они решили "задавить массой".

— Итак, господа, пришло время выбрать технологический стэк для нового проекта

— Конечно же .Net, в него больше денег вбухано!

Вы так себе это представляете?

Ну если вы выбираете стэк на ближайшие 5-10-15 лет, то при прочих равных на мой взгляд всё таки логичнее выбирать стэк, который будет больше развиваться и поддерживаться. И в который инвестируют.


И кроме того есть как минимум вероятность, что фреймворки на C# позволят в будущем целиком покрыть достаточно большие "экосистемы". То есть вам нужен будет всего один язык програмирования для бэкенда/фронтенда в вебе, десктопа под разные ОС и мобильных приложений.
Хотя это всё тоже вилами по воде написано, особенно если вспомнить тот же Silverlight.

Полностью согласен! Ведь, что такое шарп? Это виртуальная машина. И для каждого устройства надо делать свою. Ну и где тут кроссплатформенность? Пока Микрософт не соизволит портировать среду вы будете ждать. Поэтому все на Delphi! Компиляция сразу в «родной» код, хоть на андроиде, хоть на iOs, хоть в Linux
Вы ещё Java вспомните…

А задекларить в switch true?)

Не очень понял, можно пример?

switch (true)
{
case signal==Signal.Red ll signal==Signal.Yellow:

К сожалению, подобный код не поддерживает switch expression:
signal switch
{
    Signal.Red || Signal.Yellow => "stop",
    ...

В данном случае будет ошибка компиляции
А вот так ошибка рантайма, если Enum не флаг.
signal switch
{
    Signal.Red | Signal.Yellow => "stop",
    ...
Вместо такого
int ExecFull(Operation operation, int x, int y)
{
  switch (operation)
  {
    case Operation.Summ:
      logger.LogTrace("{x} + {y}", x, y);
      return x + y;
    case Operation.Diff:
      logger.LogTrace("{x} - {y}", x, y);
      return x - y;
    case Operation.Mult:
      logger.LogTrace("{x} * {y}", x, y);
      return x * y;
    case Operation.Div:
      logger.LogTrace("{x} / {y}", x, y);
      return x / y;
    default:
      throw new NotSupportedException();
  }
}

Можно написать:
int ExecFull(Operation operation, int x, int y)
{
  return operation switch
  {
    Operation.Summ => Log("{x} + {y}", x, y) ?? x + y;
    Operation.Diff => Log("{x} - {y}", x, y) ?? x - y;
    Operation.Mult => Log("{x} * {y}", x, y) ?? x * y;
    Operation.Div => Log("{x} / {y}", x, y) ?? x / y;
    _ => throw new NotSupportedException();
  };
  
  static int? Log(...)
  {
     // log someting
     return null;
  }
}
НЛО прилетело и опубликовало эту надпись здесь
Ага. Сквозной функционал лучше сделать с помощью АОП
НЛО прилетело и опубликовало эту надпись здесь
Браво! Без сарказма, очень хитроумное решение.
В C# такие хаки не очень приняты, то в том же JS половина паттернов основаны на злоупотреблении особенностями языка
Ну так и смысла в этом не особо много, первый вариант и читается лучше и поддерживать его проще.
Я и не пытался поиметь с этого практический смысл. Просто преобразовал код в вид, к которому, как мне показалось, стремился автор в исходной посылке.
К сожалению, в большом проекте у этого способа есть серьезный недостаток: никто не гарантирует отслеживание в design time расширения Ваших алгебраических типов.

Можно делать "закрытые" иерархии при помощи вложенных типов:


public abstract class Adt
{
    public sealed class Case1 : Adt
    {

    }

    public sealed class Case2 : Adt
    {

    }

    private Adt()
    {

    }
}

Это один вариантов, во что превращаются алгебраические типы данных в F# в скомпилированных сборках.

Это хороший способ, но вот нет возможности в design time проверить, что в паттерн матчинге обрабатываются все кейсы: Case1 и Case2. Как результат, при добавлении Case3 придется пройтись по всему коду. Что может привести к ошибкам, которые даже модульными тестами не отлавливаются (только интеграционными)

Видимо, я немного не понял изначальный посыл. Мне показалось, что речь была не столько про exhaustive match, сколько про неожиданное появление новых вариантов в АТД (например, другими людьми).


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


public abstract T Match<T>(T case1, T case2);

Но это уже скорее "исчерпывающее сопоставление enum`а".

Ну да, «классически» вариант паттерн матчинга через полиморфизм:
public abstract T Match<T>(Func<Child1, T> case1, Func<Child2, T> case2);
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории