你将如何使用C#4动态类型?

thi*_*ing 21 c# dynamic c#-4.0

C#4将包含一个新的dynamic关键字,它将动态语言功能引入C#.

您打算如何在自己的代码中使用它,您会提出什么样的模式?您当前项目的哪一部分将使您的代码更清晰或更简单,或启用您可能根本无法做到的事情(除了与IronRuby或IronPython等动态语言的明显互操作之外)?

PS:如果你不喜欢这个C#4,请避免负面评论.

编辑:重新发现问题.

动态的经典用法是大多数stackoverflow C#用户所熟知的.我想知道的是,如果你想到特定的新C#模式,可以有效地利用动态而不会失去太多的C#精神.

Tho*_*rin 12

现在使用老式反射,代码可读性受损.而且,正如你所说,一些Interop场景(我偶尔会使用COM).

这就是它.如果dynamic可以避免使用,则应避免使用.编译时间检查,性能等

几个星期前,我记得这篇文章.当我第一次看到它时,坦率地说,我已经做好了准备.但我没有意识到的是,我不知道如何在某种未知类型上使用运算符.我开始想知道生成的代码会是什么样的:

dynamic c = 10;
int b = c * c;
Run Code Online (Sandbox Code Playgroud)

使用常规反射,您不能使用已定义的运算符.它使用Microsoft命名空间中的一些东西生成了相当多的代码.让我们说上面的代码更容易阅读:)它很好用它,但它也慢:比常规乘法(doh)慢大约10,000倍,比ICalculator带有Multiply 的接口慢大约100倍方法.

编辑 - 为感兴趣的人生成代码:

if (<Test>o__SiteContainer0.<>p__Sitea == null)
  <Test>o__SiteContainer0.<>p__Sitea =
    CallSite<Func<CallSite, object, object, object>>.Create(
      new CSharpBinaryOperationBinder(ExpressionType.Multiply,
        false, false, new CSharpArgumentInfo[] {
          new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null),
          new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
b = <Test>o__SiteContainer0.<>p__Site9.Target(
      <Test>o__SiteContainer0.<>p__Site9,
      <Test>o__SiteContainer0.<>p__Sitea.Target(
        <Test>o__SiteContainer0.<>p__Sitea, c, c));
Run Code Online (Sandbox Code Playgroud)


Sco*_*man 7

dynamic关键字是关于简化两个场景所需的代码:

  • C#到COM互操作
  • C#以动态语言(JavaScript等)互操作

虽然它可以在这些场景之外使用,但它可能不应该使用.


Flo*_*scu 5

最近我发表了关于C#4.0动态类型的博客,其中我提到了它的一些潜在用途以及它的一些陷阱.文章本身有点太大,不适合这里,但你可以在这个地址完整阅读.

总结一下,这里有一些有用的用例(除了明显的COM库和动态语言如IronPython之外):

  • 将随机XML或JSON读入动态C#对象..Net框架包含用于将XML和JSON文档轻松反序列化为C#对象的类和属性,但前提是它们的结构是静态的.如果它们是动态的并且您需要在运行时发现它们的字段,那么它们只能被反序列化为动态对象..Net默认不提供此功能,但可以通过第三方工具(如jsonfxDynamicJson)完成
  • 从方法返回匿名类型.匿名类型的范围受限于定义它们的方法,但可以借助动态来克服.当然,这是一件危险的事情,因为您将使用动态结构公开对象(没有编译时检查),但在某些情况下它可能很有用.例如,以下方法使用Linq to SQL从DB表中只读取两列,并返回结果:

    public static List<dynamic> GetEmployees()
    {
      List<Employee> source = GenerateEmployeeCollection();
      var queyResult = from employee in source
                    where employee.Age > 20
                    select new { employee.FirstName, employee.Age };
    
      return queyResult.ToList<dynamic>();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建返回动态数据的REST WCF服务.这在以下场景中可能很有用.假设您有一个返回用户相关数据的Web方法.但是,您的服务会暴露很多关于用户的信息,并且无法始终全部返回所有这些信息.如果您能够允许消费者指定他们实际需要的字段会更好,例如使用以下URL

    http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age
    
    Run Code Online (Sandbox Code Playgroud)

    问题在于WCF只返回客户端对序列化对象做出的响应.如果对象是静态的,则无法返回动态响应,因此需要使用动态类型.然而,这里存在最后一个问题,即默认情况下动态类型不可序列化.在文章中有一个代码示例,展示了如何克服这个问题(再次,由于它的大小,我不会在这里发布).

最后,您可能会注意到我提到的两个用例需要一些解决方法或第三方工具.这让我觉得虽然.Net团队为框架添加了一个非常酷的功能,但他们可能只是将它与COM和动态语言相互补充.这将是一种耻辱,因为动态语言有一些很强的优势,并结合他们具有很强的类型语言的优势很可能把.NET和C#领先于其他开发平台的平台上为他们提供.


Ale*_*lex 1

我将使用它来简化处理 COM/Interop 的代码,在此之前我必须指定要调用的成员、其参数等(基本上,编译器不知道函数的存在,而我需要描述它)在编译时)。通过动态,这变得不再那么麻烦,代码也变得更精简。