Почему мир .Net, кажется, заключает в себе магические строки вместо статически типизированных альтернатив?

47

Итак, я работаю в .Net. Я делаю проекты с открытым исходным кодом в .Net. Одна из моих самых больших проблем с этим связана не с .Net, а с сообществом и структурами вокруг него. Повсюду кажется, что магические схемы именования и строки рассматриваются как лучший способ сделать все. Смелое утверждение, но посмотрите на это:

ASP.Net MVC:

Привет мир маршрут:

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

Это означает, что ASP.Net MVC будет как-то искать HomeControllerв вашем коде. Каким-то образом создайте его новый экземпляр, а затем вызовите функцию, Index очевидно, с idкаким-то параметром. И тогда есть другие вещи, как:

RenderView("Categories", categories);
...or..
ViewData["Foobar"]="meh";

И затем, с XAML есть похожие вещи. DataContextрассматривается как объект, и вы должны надеяться и молиться, чтобы он соответствовал тому типу, который вы хотите. DependencyProperties должен использовать магические строки и соглашения о магическом именовании. И такие вещи:

  MyData myDataObject = new MyData(DateTime.Now);      
  Binding myBinding = new Binding("MyDataProperty");
  myBinding.Source = myDataObject;

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

Во всяком случае, я говорю все это, чтобы закончить здесь: почему это так хорошо переносится в мире .Net? Разве мы не используем статически типизированные языки, чтобы почти всегда знать, что это за вещи? Почему рефлексия и тип / метод / свойство / любые имена (как строки) так предпочтительны по сравнению с обобщениями и делегатами или даже генерацией кода?

Существуют ли унаследованные причины, по которым мне не хватает того, почему синтаксис маршрутизации ASP.Net полагается почти исключительно на рефлексию, чтобы фактически решить, как обрабатывать маршрут? Я ненавижу, когда я изменяю имя метода или свойства и вдруг что-то ломается, но, похоже, нет никаких ссылок на этот метод или свойство, и, конечно, нет ошибок компилятора. Почему очевидное удобство волшебных струн считалось «стоящим»?

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

Earlz
источник
14
Бесполезный динамизм был в моде с тех пор, как наши процессоры были достаточно быстры, чтобы выполнить его.
DeadMG
7
Как так? Я не видел таких примеров с LINQ.
DeadMG
6
Мое скромное предположение состоит в том, что правильно подобранная статически альтернатива слишком неприятна. Эта тема часто встречается в большинстве систем типов: «Мы хотели бы сделать это в системе типов, но она недостаточно выразительна». (Или наоборот: «Мы успешно выразили это в системе типов, но она усложнила ситуацию в три раза».) @ GlenH7 Я не очень знаком со всеми LINQ, но использованные биты не показывают что-нибудь даже около того, что описывает этот пост. Хотите привести пример?
2
@Earlz Что еще более важно, анонимные объекты статически типизированы. Волшебных строк нет, компилятор знает имя и тип всего, что с этим связано. Сохранить для любого другого использования var.
1
@Earlz, это интересно, хотя можно утверждать, что лямбда-синтаксис является дополнительным раздуванием здесь. Я предполагаю, что они придерживались подхода магической струны / соглашения, потому что он очень простой, «достаточно хороший» для многих, и они всегда могут адаптировать инструмент, чтобы дать некоторое руководство / безопасность. Это компромисс между безопасностью и удобством, ИМХО. Использование динамического ViewBag также намекает на этот менталитет (не то, чтобы я полностью с ним согласился).
Даниэль Б

Ответы:

31

На самом деле в мире .NET есть толчок к тем самым вещам, о которых вы упомянули. Однако в первом примере, который вы дали, механизму маршрутизации дано соглашение для отображения маршрута по умолчанию. Сам факт, что маршруты являются динамическими, делает почти невозможным использование статической конфигурации.

Вы также упоминаете XAML / WPF, оба из которых разрабатывались задолго до того, как дженерики были введены в .NET, и возвращение к поддержке дженериков задержало бы уже очень поздний продукт (Longhorn / Vista) еще больше.

В рамках ASP.NET MVC есть примеры использования лямбда-выражений вместо магических строк, и Entity Framework / LINQ продвигает это еще дальше, когда язык и инфраструктура предоставляют встроенную поддержку для составления запросов SQL через статический граф объектов (вместо создания Волшебные строки SQL, вы получите проверку времени выполнения ваших запросов).

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

Таким образом, краткий ответ заключается в том, что исторически .NET не поддерживал статический обход графа объектов до выпуска 3.5. Теперь, когда он у нас есть, многие разработчики предпочитают его магическим строкам, и многие стремятся к еще более глубокой поддержке, такой как оператор symbolOf, который работает аналогично оператору typeOf.

Майкл Браун
источник
3
XAML многословен как есть ... добавление поддержки дженериков сделало бы это еще более значительным (да, я знаю, что весь XAML не создан для людей, Аргумент). Кроме того, я считаю XAML более похожим на HTML, чем на язык программирования. Он не должен заботиться о типе отображаемых объектов, а только о том, как его отображать.
Майкл Браун
2
Дженерики появились в 2.0, но мы не получили Expressions до 3.5 (с LINQ). Выражения - это то, что дает LINQ и сообществу возможность использовать это и работать с ним. Техника известна как статическое отражение
Майкл Браун
1
Хороший вопрос о статическом отражении. Я забыл об этом введении в 3.5
Earlz
2
Это отличный ответ, и я определенно согласен с откатом. Все эти вещи я избегаю, как чума, потому что, если есть опечатка или ошибка, они обнаруживаются только во время выполнения, то есть их очень легко пропустить. Они также делают рефакторинг чрезвычайно разным. Избегать избегать избегать!
Rocklan
2
Согласитесь на откат. T4MVC - проект, который напоминает, что стремится удалить много строк и заменить их строго типизированным кодом.
Carson63000