Pull to refresh
56
0

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

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

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

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

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

А теперь давайте вспомним, что проверки на константы должны идти раньше проверок на типы, а null — это тоже константа. И где тут логика?
Не должны, 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...
Разная спецификация типа — это для вас минимально отличающаяся запись?
var для меня означает лишь вывод типа из контекста выражения, а не разную спецификацию. Тот факт, что на него навесили странную дополнительную логику, нарушив принципы разделения ответственности и грамотной композиции, лежит уже на совести архитекторов. Я просто не поддерживаю их решение, используя свои кастомные модификации с чистой интуитивной имплементацией.

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

Вот только они мне об этом скажут, когда я код уже скопировал и вставил. Я бы, знаете, предпочел такого избегать.
А я предпочту избежать гораздо более рутинной и неудобной реструктуризации кода при замене конструктора на метод-фабрику.
«Сложного» здесь то, что теперь есть две конструкции, отличающиеся друг от друга минимально, с разным (но не всегда!) поведением.
Да? А как насчёт минимально отличающихся с разным, но не всегда, поведением?
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# два раза объявить переменную в одном контексте нельзя. Или я вас неправильно понял?
Не понимаю с чем вы спорите.
Не спорю вовсе. Выражаю личную точку зрения на поднятые вопросы и отвечаю на критику.
Не понимаю, что тут сложного… 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.
Объявления переменных весьма органично вписываются в контекст цепочных вызовов, поэтому ошибиться в этом довольно-таки трудно. :)
Или понимаем, что в конкретном случае совсем не важен результат выполнения метода, а важен лишь факт его вызова.

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

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

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

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

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

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

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

Собрали дошколят и говорят: «Дети! Мы будем проводить исследование по влиянию фантазирования на развитие вашего мышления! Теперь вы должны фантазировать строго по нашему расписанию на определённые темы на проятяжении пятнадцати лет, а попутно мы будем проводить разные-разные тесты… Для убедительности одну подгруппу мы ограничим в фантазировании, а другую будем стимулировать к этому… и т. д. и т. п.»

Или, может, сделать опросник для взрослых людей?
Как часто вы фантазированли в возрасте до пяти лет? До десяти?.. В какие игры играли? В какие кружки ходили? Сколько времени уделяли этим занятим? Какие книжки прочитали? Какие мультики посмотрели и по сколько раз? С кем дружили? Как часто гуляли?..

Или лучше возьмём близнецов, которых разлучили в детстве! Гениально! Изучим вляние среды на развитие близнецов…

Вот только даже в генетике, где всё чуть более детерменировано, чем в психическом развитии, исследования близнецов выявили ряд корреляций, оказашихся в последствии ошибочными… У Роберта Сапольского есть интересная лекция, где затронута тема исследования близнецов.

Как бы там ни было, для объективного исследования и детального прослеживания закономерностей настолько комплексных и фундаментальных явлений, как фантазирование и развитие мышления, на текущем этапе развития человечества невозможно воссоздать необходимые «чистые» условия. И вообще, хороший вопрос, возможно ли такое в принципе?..

Максимум, что сейчас нам доступно — это поиск очевиднейших корреляций, например, что набор определённых мутаций в генах серьёзно повышает риск возникновения дименции в старости или такие-то гены, ответсвенные за развитие речевых центров отличают нас от других приматов.

Вы же меня просите о невыполнимой вещи, предоставить вам ссылки на исследования, которых не существует. Современная формализованная наука только-только начинает соприкасаться с такими вещами. Другое дело — житейский опыт. Если с ребёнком достаточно заниматься, учить его, развивать, играть, стимулировать фантазию, то всё это способствует развитию его мышления! Да, не факт, что из ребёнка вырастет выдающийся учёный, но тенденции к тому, что человек будет образованный и развитый, намного больше.
Тот, кто сможет верно рассчитать интегрированием площать прямоугольного треугольника, как минимум, уже разбирается в основах интегрирования. И, уж наверняка, сможет подсчитать площадь треугольника классическим способом.
Меньше кода, меньше оверхеда, лучше читается, никакого WTF. Деконструкция здесь просто не нужна.
Вы, похоже, не уловили сути. Деконструкция и инициализация с With позволяют выводить, объявлять и обновлять значения где угодно в цепочных вызовах без кардинальной смены структуры кода.
string _newName = "abc";

bool UpdateData(Person p) => p.With(
    p.Name.To(out var oldName),
    p.Name = _newName)
)
.Use(() => Debug.WriteLine($"Name changed  from {oldName} to {_newName}"))
.TrySave();

Например, тут присутствует временный дебажный вывод, который может быть легко удалён без смены структуры кода.
string _newName = "abc";

bool UpdateData(Person p) => p.With(
    p.Name = _newName)
)
.TrySave();


(o, e) =>
{
if (App.Current.MainWindow is Window w)
w.Title = «x»;
};

With для того мне и нужен, чтобы избежать скобок и конструкций вида if-else, вы же предлагаете мне вернуться к старому варианту, который всегда был мне не по душе. И да, я хочу использовать вывод типов без всяких хаков, а не указывать их явно как Window w.
Это смотря с чем сравнивать. Ну да, F# мне нравится больше. Но F# имеет свои занятные особенности (и с вашей манерой писать совместим, кстати, исключительно плохо).

Активно не использую F#, но реализация паттерн-матчинга там чище, чем в C#. Хотя и он меня вполне устраивает, особенно с кастомными To-With-Is-Check.

Information

Rating
Does not participate
Registered
Activity