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

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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.