百科问答小站 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#4天,用记事本1分钟写个计算器,而且信誓旦旦,这是怎么回事? 
  微软宣布xamarin免费,对其他跨平台方案有什么冲击?对C#有什么影响? 
  为什么 WinFX 未能取代 Win32? 
  .Net中 编写 异步WebAPI 到底有何好处? 
  为什么 C#/.Net在国内的人气远不如国外? 
  如何看待go语言泛型的最新设计? 
  用 C# 写个方法解析简单的 JSON 字符串有哪些思路? 
  你见过哪些令你瞠目结舌的C#代码? 

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





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