【问题标题】:C# 4: Real-World Example of Dynamic TypesC# 4:动态类型的真实示例
【发布时间】:2011-01-16 09:25:16
【问题描述】:

我认为我的大脑已经围绕 C# 4 中的动态类型概念进行了一半的思考,但我终其一生都想不出我真正想要使用它的场景。

我敢肯定有很多,但我只是在建立联系时遇到了麻烦,我无法设计一个解决方案,该解决方案通过动态而不是接口、依赖注入等来更好地解决。

那么,适合动态类型使用的真实应用场景是什么?

【问题讨论】:

  • 除了 COM 对象,我坚信它们在 C#/.NET 中实际上并不是特别有用,而且几乎总是存在更好的解决方案......
  • 哦,当然还有像 IronPython 这样的动态语言。它是纯 C#,但它没有位置。
  • @Noldorin:您只需要再提一件事,就可以将我的整个答案重复为问题的 cmets。 ;)
  • @Mark:嘿,是的。当我第一次发表评论时,实际上并没有正确阅读它,但似乎我们主要在同一时间写相同的东西。 :P

标签: c# .net


【解决方案1】:

在很多情况下,您已经使用动态类型和动态绑定今天。你只是没有意识到,因为它都隐藏在字符串或 System.Object 后面,因为直到 C# 4 之前,还没有必要的支持。

一个例子是COM互操作:COM实际上是一个半动态的对象系统。当你做 COM 互操作时,很多方法实际上返回一个动态对象,但是因为 C# 不支持它们,所以它们返回为 System.Object 并且你必须自己强制转换它们,可能会在途中捕获异常。

另一个例子是与动态类型(甚至是非类型)数据交互,例如 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 实例。

【讨论】:

  • 嗯...有趣,但我无法让这些示例在 C# 4.0 中工作。我做错了吗?
  • @DanM:要让这些假设的例子起作用,你显然必须首先实现假设的 API,即你必须实际编写 XmlDocument 和 @987654328 @ 支持此 API 的类。我认为后者应该很明显。
  • 啊,我现在明白了。 (让我困惑的是XmlDocument已经是.NET框架中的一个类了。)
【解决方案2】:

MSDN 上有一个例子:

许多 COM 方法通过将类型指定为对象来允许参数类型和返回类型的变化。这需要显式转换值以与 C# 中的强类型变量协调。如果您使用 /link(C# 编译器选项)选项进行编译,则动态类型的引入使您能够将 COM 签名中出现的对象视为动态类型,从而避免大量转换。

另一个例子是如果您必须与动态语言进行互操作。

在某些情况下,您希望使某些代码通用但您不能,因为即使对象实现相同的方法,它们也不共享合适的基类或接口来声明您需要的方法。这方面的一个例子是试图用 int 和 short 来做一些通用的东西。这有点小技巧,但动态允许您在这些不同类型上调用相同的方法,从而允许更多的代码重用。

更新:在这里搜索了一下发现this related post。

【讨论】:

    【解决方案3】:

    来自 Walter Almeida 的博客:在 C# 中使用 dynamic 关键字增强面向对象的场景:

    http://blog.walteralmeida.com/2010/05/using-the-dynamic-keyword-in-c-to-improve-objectorientation.html

    【讨论】:

      【解决方案4】:

      Scott Watermasysk 写了一篇关于在 MongoDB C# 驱动程序上使用动态进行字典键属性映射的文章。

      http://simpable.com/code/mongodb-dynamics/

      【讨论】:

        【解决方案5】:

        到目前为止,我认为其他人已经给出了一些很好的答案,所以我只想添加 David Hanson 的这个例子。他的帖子展示了迄今为止我发现的最实用的 C# 动态类型应用程序,他使用它们来创建代理对象。在此示例中,他创建了一个代理,该代理允许在 WPF 绑定错误时引发异常。我不确定在 WPF 绑定的情况下是否也可以通过使用 CustomTypeDescriptors 和属性描述符概念来实现这一点,但无论如何我认为使用新的 C# 4.0 动态类型很好地展示了它的功能。

        Raising binding exceptions in WPF & Silverlight with .net 4.0 Dynamics

        我能想到的动态类型的另一个用途是创建代理,这些代理同样可以作为 DataContext 插入 WPF 或其他需要通用对象类型并且通常使用反射方法来询问类型的地方.在这些情况下,尤其是在构建测试时,可以使用动态类型,然后允许代理对象以动态方式调用和记录属性访问器,而无需在仅测试类中硬编码属性。

        【讨论】:

          【解决方案6】:

          我读到了 Scott Hanselman 的一篇有趣的文章(附件)。他指出,与使用对象相反,您可以使用动态从编译器不知道方法存在的旧 COM 对象中引用方法。我发现这个链接很有用。

          Scott Hanselman - C#4 and the dynamic keyword

          【讨论】:

            猜你喜欢
            • 2023-04-09
            • 2017-02-09
            • 1970-01-01
            • 1970-01-01
            • 2020-05-11
            • 2013-08-14
            • 2016-11-16
            • 1970-01-01
            相关资源
            最近更新 更多