Как стать автором
Обновить
29
Карма
0
Рейтинг

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

  • Подписчики 41
  • Подписки 3

Правостороннее присваивание и другие необычные приёмы программирования в C#

Во-первых, конструктор коллекции может быть защищённым в некоторых случаях, при использовании сторонних библиотек, например.

Во-вторых, не знаю, как для вас, но для меня цепочные вызовы выглядят намного более структурировано и читаемо.

Так вот, я против написания кода, который позволяет делать неконсистентные структуры данных.
А я не против. )

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

Исправлять ли unexpected behavior в C# 7 или оставить как есть, усложнив синтаксис языка для компенсации?

Ха-ха-ха, нашли спамера. Увы, ваши утверждения насчёт is var / case var обоснованы ещё меньше.

Так никогда не пробовали написать?
switch (new object())
{
  case string s:
    return;
  case 5:
    return;
}

Правостороннее присваивание и другие необычные приёмы программирования в C#

Затем же, зачем и With паттерн, потому что инициализационный блок — это всего лишь его частный случай с неявной переменной, чуть более лаконичным синтаксисом, но более ограниченными возможностями.

Правостороннее присваивание и другие необычные приёмы программирования в C#

У вас у коллекции нет конструктора с множеством элементов? Сочувствую.
Да? Как насчёт
ReadCollectionFromFile().To(out var c)
.With(c.Name = "abc")
.Merge(item1, item2, GetItem3(), item4)...

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

… что не имеет никакого отношения к замене конструктора на фабричный метод.
Имеет, фабричный метод вполне может инициализировать ссылочные переменные дефолтными инстенсами, если нужно.
Person CreatePerson() => new Person {
    City = new City { Name = "unknown" }
};

Исправлять ли unexpected behavior в C# 7 или оставить как есть, усложнив синтаксис языка для компенсации?

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

И ещё такой момент — здесь много «корпоративной политики», ибо зачем блокировать в репозитории пользователя, который вовсе не нарушал правил поведения, а просто отстаивал альтернативную точку зрения? Тем более, если она настолько слабая и не выдерживает авторитетной критики…

А теперь давайте вспомним, что проверки на константы должны идти раньше проверок на типы, а null — это тоже константа. И где тут логика?
Не должны, C# допускает произвольный порядок проверок на типы и значения. Как их размещать, в зависимости от требуемой логики, дело разработчика.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Правда? То есть ваш прекрасный пример «а вот тут был дебаг» никому никогда не надо повторять для каждого шага в цепочке, которых бывает много?
Слабо понимаю вашу критику, но если вы примитивно копипастите код из одного места в другое, то конфликт имён может произойти, где угодно. Простите, но, скажу прямо, для меня такая проблема выглядит высасонной из пальца. Кроме того, вы не замечаете, как решаются конфликты другого рода, неразрешимые на текущий момент в терминах инициализационных блоков. Например,
new NamedCollection().To(out var c)
.With(c.Name = "abc")
.Merge(item1, item2, GetItem3(), item4)...

И весьма интересный сценарий с замыканием графа
var tree = new Node().To(out var r).With(
    r.Child = new Node().To(out var c).With(
        c.Root = r
    )
);

Это той самой реструктуризации, которую современные IDE делают в один клик?
К сожалению, IDE не может понять, когда нужен p.City?.With(...), а когда p.City = new City...

Исправлять ли unexpected behavior в C# 7 или оставить как есть, усложнив синтаксис языка для компенсации?

Разная спецификация типа — это для вас минимально отличающаяся запись?
var для меня означает лишь вывод типа из контекста выражения, а не разную спецификацию. Тот факт, что на него навесили странную дополнительную логику, нарушив принципы разделения ответственности и грамотной композиции, лежит уже на совести архитекторов. Я просто не поддерживаю их решение, используя свои кастомные модификации с чистой интуитивной имплементацией.

Долго пытался выяснить объективные причины, зачем это было необходимо и почему не сделали более грамотно, но один из архитекторов языка (признав, что это хоть и болячка) мотивировал решение острой необходимостью данной конструкции в выражениях вида is {… } x и case {… } x и тем, что команда дизайна верит в это решение. К сожалению, на аргументированную критику и предложенный альтернативный и более функциональный Check-паттерн (аналог With) никто из команды мне больше не ответил.
Правда в произвольном? А если вам надо сравнить с еще одной константой?
Произвольном в контексте данного примера, если вы меняете пример, то порядок может иметь значение.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Современные IDE позволяют запросто переименовывать переменные, если нужно, а учитывая, что нацелено расширение на цепочные вызовы в expression bodied конструкциях, то вероятность возникновения коллизии имён с другими переменными минимальна.

Вот только они мне об этом скажут, когда я код уже скопировал и вставил. Я бы, знаете, предпочел такого избегать.
А я предпочту избежать гораздо более рутинной и неудобной реструктуризации кода при замене конструктора на метод-фабрику.

Исправлять ли unexpected behavior в C# 7 или оставить как есть, усложнив синтаксис языка для компенсации?

«Сложного» здесь то, что теперь есть две конструкции, отличающиеся друг от друга минимально, с разным (но не всегда!) поведением.
Да? А как насчёт минимально отличающихся с разным, но не всегда, поведением?
switch (GetPoint())
{
  case object x:
    break;
  case var x:
    break
}

На мой взгляд,
switch (GetPoint())
{
  case var x:
    break;
  default var x:
    break
}

либо
switch (GetPoint())
{
  case object x:
    break;
  default object x:
    break
}

существенно более интуитивно, благодаря ключевому слову default.

В нем нет ничего неожиданного.
Для вас нет, а для меня это «грязный» синтаксис, которого я просто избегаю.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Так что ошибиться легко, достаточно два раза подряд объявить одну переменную.
Эм-м-м… Среда разработки и компилятор вам срузу об этом скажут, в C# два раза объявить переменную в одном контексте нельзя. Или я вас неправильно понял?

Правостороннее присваивание и другие необычные приёмы программирования в C#

Не понимаю с чем вы спорите.
Не спорю вовсе. Выражаю личную точку зрения на поднятые вопросы и отвечаю на критику.

Исправлять ли unexpected behavior в C# 7 или оставить как есть, усложнив синтаксис языка для компенсации?

Не понимаю, что тут сложного… case var x будет срабатывать всегда, когда метод возвращает не null, в случае null сработает default var x.

Наоборот удобно, если мне нужно по особому обрабатывать null, то пишу
switch (GetPoint())
{
  case var x: // logic for non null
    break;
  case null: // special logic for null
    break
}

Причём, кейсы можно размещать в произвольном порядке! А в другом случае
switch (GetPoint())
{
  default var x: // common logic for null and non null
    break;
}


Вот только оно вводит общую переменную, видную во всех кейсах, а зачем она мне?
IMHO Покрасивше выглядит, чем unexpected case var.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Объявления переменных весьма органично вписываются в контекст цепочных вызовов, поэтому ошибиться в этом довольно-таки трудно. :)

Правостороннее присваивание и другие необычные приёмы программирования в C#

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

Состояние определено после вызова Expose — остальное не имеет значения в данном контексте.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Ключевые слова async и await формально тоже не являются частью C#? Где границы этой формальности? Может, просто не стоит возводить формальность в культ, а прибегать к ней по мере надобности?

Правостороннее присваивание и другие необычные приёмы программирования в C#

Деньги — это косвенный и комплексный фактор фактор. Можно быть богачём и спускать их на ветер, а можно быть середнячком и вкладывать в развитие и образование — эффект будет совершенно разный. А бывает, денег не хватает, даже чтобы оплатить школу…

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

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

Правостороннее присваивание и другие необычные приёмы программирования в C#

Если вам не по душе императивное программирование, зачем вы издеваетесь над императивным языком?

Только лишь приспасабливаю язык под свои индивидуальные нужды, а заодно исследую нестандартные сценарии использования базовых конструкций.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Конечно, например, как вы забыли о существовании холодных тасков.

Но ведь это не делает человека глупее или некомпетентнее, хотя формально вы могли завалить тест по C# из-за этого вопроса… Важно понимание сути самой темы. Задача оценивающего — выяснить, насколько близко подобрался к этому экзаменуемый.

Правостороннее присваивание и другие необычные приёмы программирования в C#

Тому ученику, который расчитал бы площадь треугольника классическим способом, я бы поставил пять. Тому, кто двумя способами, пять с плюсом…

Если бы попался человек, который умеет расчитываеть площадь треугольников интегрированием, но не знает классического, то я бы получше присмотрелся к нему и задал бы ряд уточняющих вопросов…

Информация

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