为什么.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
自从我们的CPU足够快地执行它以来,毫无意义的动态就一直风行一时。
DeadMG

7
怎么会这样?我还没有在LINQ上看到过这样的例子。
DeadMG

6
我谦虚的猜测是,正确地静态类型化的替代方案非常不便。这个主题实际上在大多数类型系统中都得到了体现:“我们想在类型系统中做到这一点,但表现力不足。” (或者相反:“我们成功地在类型系统中表达了这一点,但是它使事情复杂了三倍。”)@ GlenH7我对LINQ并不是很熟悉,但是我使用的位并没有表现出来甚至与这篇文章描述的内容无关。想举个例子吗?

2
@Earlz更重要的是,匿名对象是静态类型的。没有魔术字符串,编译器知道所涉及的一切的名称和类型。保存为的其他所有用途var

1
@Earlz很有趣,尽管有人可能会说lambda语法是这里的另一个膨胀。我的猜测是他们采用了魔术字符串/约定方法,因为它非常简单,对许多人来说“足够好”,并且他们总是可以改编该工具以提供一些指导/安全性。恕我直言,这是在安全性和便利性之间做出的取舍。动态ViewBag的使用也暗示了这种心态(并非我完全同意)。
丹尼尔·B

Answers:


31

实际上,.NET世界中存在针对您提到的这些问题的后退。但是,在您给出的第一个示例中,为路由引擎提供了映射默认路由的约定。由于路由是动态的,因此几乎不可能使用静态配置。

您还提到了XAML / WPF,这两者在将泛型引入.NET之前都处于开发阶段,而返回支持泛型将使已经很晚的产品(Longhorn / Vista)进一步延迟。

在ASP.NET MVC框架中,有一些示例可以使用lambda表达式代替魔术字符串,而Entity Framework / LINQ则更进一步,其中语言和框架为在静态对象图上构成SQL查询提供了本机支持(而不是构造魔术SQL字符串,您将获得查询的编译时验证)。

有关静态配置的其他示例,请参见structuremap和其他现代依赖项注入容器,以及其他需要在运行时检查对象图但允许开发人员使用lambda表达式静态提供提示的框架。

因此,简短的答案是,从历史上讲,.NET直到3.5版本才支持对象图的静态遍历。现在我们有了它,许多开发人员都喜欢使用它而不是魔术字符串,并且许多人一直在寻求更深层次的支持,例如symbolOf运算符,其工作方式与typeOf运算符类似。


3
XAML太冗长了……添加对泛型的支持将使它变得更加如此(是的,我知道整个XAML并不是为人类争论而设计的)。此外,我认为XAML比实际的编程语言更类似于HTML。它不应该关心所显示对象的类型,而只关心其显示方式。
迈克尔·布朗

2
泛型出现在2.0中,但是直到3.5(使用LINQ)我们才获得Expressions。表达式是LINQ的力量,社区已经掌握并使用了它。该技术被称为静态反射
Michael Brown

1
关于静态反射的要点。我忘记了将其引入3.5
Earlz,2013年

2
这是一个很好的答案,我绝对同意后撤。所有这些事情我都避免像瘟疫一样,因为如果有错别字或错误,它们只会在运行时被捕获,这意味着很容易错过它们。它们也使重构极为不同。避免避免避免!
罗克兰

2
同意后退。T4MVC是一个让人大跌眼镜的项目,它希望删除许多字符串并用强类型代码替换它们。
Carson63000
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.