百科问答小站 logo
百科问答小站 font logo



C#的dynamic使用中有什么需要注意的地方,以免滥用? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

dynamic和generic type完全是两码事儿,dynamic不能弥补generic type。

诸如操作符的问题,应该用强类型接口解决。像这种所谓用dynamic弥补generic type的做法就是滥用,就是应当避免的。


dynamic的主要意义在于他只是一个表达式,而这个表达式的行为可以被动态对象在运行时重新诠释。从这一点上来说,dynamic和IQueryable有点类似。

譬如说,data.A,如果data是一个静态类型,那么这个A的意义就是编译时就确定的,但是如果data是dynamic,那么你可以在运行时再来决定这个data.A到底代表一个什么含义,甚至于你可以让data.A在不同的表达式之中表现出不同的行为出来,这才是dynamic不可替代的优势。

譬如说dynamic可以轻易地实现当data.A是null的时候,data.A.Name也是null,而不会报错,这对于一些特定的场合,例如数据绑定,是非常有用的。同时也可以使得在data.A+i这样的表达式中,data.A的值看起来就和0一样。


判断dynamic是不是被滥用了,我觉得一个比较简单的办法就是,除非你重写了IDynamicMetaObjectProvider对象,否则就是滥用,dynamic的意义在于运行时重新诠释表达式的行为,而默认的dynamic行为就是反射的一个语法糖而已。通过重写IDynamicMetaObjectProvider来重新诠释表达式的行为,则应当是被鼓励的,正确使用dynamic的形式。


例如ASP.NET MVC中使用dynamic作为ViewData索引器的语法糖,JSON.NET中作为修改JObject对象修改的语法糖,而我的DataPithy开源项目中,也使用dynamic作为DataRow对象成员访问的语法糖,通过dynamic,使得这些对象的访问变得简单,而性能也基本没有损失。


========================================================

补充一些东西:


1、提问者的问题本质:C++的模板的一些高级用法能否用C#的dynamic弥补。

不能。本质上有很大的区别,C++的模板是编译时展开的,这样才带来了一些高级的用法,而且不必声明类型约束,在展开时如果发现无法编译的情形直接在编译期就会报错。

而C#的泛型是在运行时展开,所以需要声明类型约束,在编译后还能继续对未知类型展开,这些都是优势,但由于缺乏运算符约束,像T+T这种运算无法写出来。

使用dynamic本质上是把+的运算放到运行时再由CSharpBinaryOperationBinder来处理,这样一来性能有大数量级的损失。实现原理完全不一样,性能差异巨大,所以不能作为C++模板的替代方案

2、如果是做一个类似脚本的计算引擎场景,则应当直接拼接表达式树,避免计算结果,而是在最后对表达式树编译再运行计算,比分步计算结果性能要好。或者直接用DLR来处理,去除中间过程中没有必要的类型转换。

3、动态语言的重构显然不如静态语言来的方便,但也不至于成为一场灾难。严格控制动态类型的应用范围,避免多层级跨模块的动态调用,配合文本搜索,也能做动态类型的重构。当然,利用动态类型的特性,也可以在动态类型层面做向下兼容,例如属性A改成了B,那么继续保留A并重定向到B即可。




  

相关话题

  为什么叫.NET?它和C#是什么关系? 
  C#程序如何调用Python程序? 
  C#的async和await底层是怎么做到的? 
  为什么听说过 JVM 调优,却没听说过 CLR 调优? 
  微软开放.net框架源代码后,未来的发展有哪些可期待的? 
  如何评价Jexus V5.8.0 发布被人砸场? 
  如何看待go语言泛型的最新设计? 
  (PHP、.net、JSP)哪一只能实现花生壳的功能? 
  c#启动有什么好的优化技巧? 
  微软的市值高达2.3万亿美元,相当5个腾讯,8个阿里巴巴。这种巨无霸级的公司,为啥.Net国内这么差? 

前一个讨论
如何反驳「如果唐七不抄,我们就看不到那么多优美而又打动人心的句子了」的观点?
下一个讨论
类(class)能不能自己继承自己?





© 2024-12-22 - tinynew.org. All Rights Reserved.
© 2024-12-22 - tinynew.org. 保留所有权利