我认为我的大脑已经在C#4中的动态类型概念中徘徊,但是在我的生活中不能找到我真正想要使用它的场景。
我确信有很多,但我只是无法建立连接,以便我能够设计出一个更好的解决方案,而不是接口,依赖注入等。
那么,动态类型使用是否合适的真实应用场景是什么?
答案 0 :(得分:63)
在很多情况下,已经使用动态类型和动态绑定今天。你只是没有意识到这一点,因为它全都隐藏在字符串后面或System.Object
,因为直到C#4,才有必要的支持。
一个例子是COM互操作:COM实际上是一个半动态对象系统。当您进行COM互操作时,很多方法实际上返回一个动态对象,但由于C#不支持它们,它们被返回为System.Object
并且您必须自己投射它们,可能在途中捕获异常。 / p>
另一个例子是与动态类型(甚至无类型)数据交互,例如JSON,CSV,HTML,无模式XML,无模式Web服务,无模式数据库(毕竟,它们是新的热点)。今天,你使用字符串。 XML API看起来像
var doc = new XmlDocument("/path/to/file.xml");
var baz = doc.GetElement("foo").GetElement("qux");
等等。但是如何:
dynamic doc = new XmlDocument("/path/to/file.xml");
var baz = doc.foo.qux;
这看起来不是很好吗?
第三个例子是反思。今天,通过将一个字符串传递给InvokeMember
(或任何调用的东西)来完成通过反射调用方法。你知道吗,只是援引这该死的东西不是更好吗?
然后,有动态数据的代(基本上与第二个例子相反)。以下是如何生成一些动态XML的示例:
dynamic doc = new XmlBuilder();
doc.articles(id=42, type="List", () => {
article(() => {
number(42);
title("blahblubb");});});
这并不像同等的Ruby那么漂亮,但它是我在这么短的时间内想出来的最好的: - )
最后但并非最不重要的是,与动态类型语言集成。无论是Silverlight应用程序中的JavaScript,嵌入在您的业务应用程序中的自定义规则引擎,还是您在CAD程序/ IDE /文本编辑器中托管的DLR实例。
答案 1 :(得分:3)
MSDN上有一个例子:
许多COM方法允许通过将类型指定为对象来改变参数类型和返回类型。这需要显式转换值以与C#中的强类型变量进行协调。如果使用/ link(C#编译器选项)选项进行编译,则动态类型的引入使您可以将COM签名中对象的出现视为动态类型,从而避免大量转换。
另一个例子是如果你必须与动态语言互操作。
在某些情况下,您希望将某些代码设置为通用,但您不能这样做,因为即使对象实现了相同的方法,它们也不会共享一个合适的基类或接口来声明您需要的方法。这方面的一个例子是尝试使用int和short来创建通用的东西。这有点像黑客,但动态允许你在这些不同的类型上调用相同的方法,允许更多的代码重用。
更新:在此处进行了一些搜索this related post。
答案 2 :(得分:3)
来自Walter Almeida的博客:在C#中使用动态关键字来增强面向对象的场景:
答案 3 :(得分:2)
Scott Watermasysk写了一篇关于在MongoDB C#驱动程序上使用动态进行字典键属性映射的文章。
答案 4 :(得分:2)
我认为其他人到目前为止给出了一些很好的答案所以我只想添加David Hanson的这个例子。 Hist post显示了迄今为止我发现的C#中动态类型最实用的应用程序,他使用它们来创建代理对象。在此示例中,他创建了一个代理,允许在WPF绑定错误上引发异常。通过使用CustomTypeDescriptors和属性描述符概念,我不确定在WPF绑定的情况下是否也可以实现这一点,但无论我认为使用新的C#4.0动态类型都能很好地证明其功能。
Raising binding exceptions in WPF & Silverlight with .net 4.0 Dynamics
我可以想到的另一个用于动态类型的用法是创建代理,类似地可以插入WPF中的DataContext或其他需要通用对象类型的地方,并且通常使用反射方法来查询类型。在这些情况下,尤其是在构建测试时,可以使用动态类型,然后允许通过代理对象以动态方式相应地调用和记录属性访问器,而无需在仅测试类中硬编码属性。
答案 5 :(得分:1)
我读了Scott Hanselman撰写的一篇有趣的文章(附后)。他指出,与使用对象相反,您可以使用动态来引用旧COM对象中的方法,其中编译器不知道存在方法。我发现链接很有用。