博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#学习之动态化--dynamic
阅读量:6930 次
发布时间:2019-06-27

本文共 2944 字,大约阅读时间需要 9 分钟。

什么是动态,什么又是动态语言运行时

动态即为在编译的时候不执行类型检查,仅在运行时识别对象的类型。这样的话,如果调用了一个类型没有的方法或是属性,在编译的时候并不会报错,但在运行时才会捕获这些错误信息。

编程语言可分为静态化语言和动态话语言,C#最初是设计为纯静态化语言,但为了改进与动态语言和框架之间的互操作性,最终决定利用dynamic关键字来支持这一功能。

 

ExpandedBlockStart.gif
View Code
 1  
public 
static 
void M(dynamic arg)
 2     {
 3         dynamic result = arg + arg;
 4         Console.WriteLine(arg.GetType() + 
"
:
" + result);
 5     }
 6     
static 
void Main(
string[] args)
 7     {
 8         
for (
int i = 
0; i < 
2; i++)
 9         {
10             dynamic d = (i == 
0) ? 
5 : (dynamic)
"
Demo
";
11             M(d);
12         }
13     }
14     
//
output:
15 
    
//
System.Int32:10
16 
    
//
System.String:DemoDemo

 

如上所见,能把不同的类型对象分配给dynamic变量,并在运行时确定对象的类型,已经执行相应的操作,如int类型,+执行求和,而对于string执行连接。

那么,在编译时,c#编译器到底是如何解析dynamic类型啦,我们通过IL看下方法M的定义:

 

ExpandedBlockStart.gif
View Code
 1  .method 
public hidebysig 
static 
void  M(
object arg) cil managed
 2   {
 3     .param [
1]
 4     .custom instance 
void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 
01 
00 
00 
00 ) 
 5     
//
 Code size       448 (0x1c0)
 6 
    .maxstack  
15
 7     .locals init ([
0
object result,
 8              [
1
class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$
0$
0000)
 9     IL_0000:  nop
10     IL_0001:  ldsfld     
class [System.Core]System.Runtime.CompilerServices.CallSite`
1<
class [mscorlib]System.Func`
4<
class [System.Core]System.Runtime.CompilerServices.CallSite,
object,
object,
object>> Program/
'
<M>o__SiteContainer0
'::
'
<>p__Site1
'
11     IL_0006:  brtrue.s   IL_0041

      实际上,代码使用dynamic表达式/变量来调用一个成员时,编译器会生成特殊的IL代码来描述所需的操作,这种特殊的代码称为payload(有效载荷)。而对于dynamic类型,实际上被解析为object类型,此外,对于像property,方法参数,编译器还会为此加上一个DynamicAttribute,而对于方法内部的局部定义的dynamic类型,是不会加这个attribute的。

 

动态运行时,即Dynamic Language Runtime(DLR).首先它实现了动态语言和.NET Framework之间的互操作,其次,它将动态行为引入C#和Visual Basic之中。

C#语言环境中的dynamic概念指的就是关键字dynamic和DLR。

 

Dynamic, object and Var之间的区别

object表示System.Object类型,是C#类层次结构中的根类型。object一般是在编译时无法确定对象类型时使用,它经常运用在各种互操作性情形中。object经常会有显示转换问题:

ExpandedBlockStart.gif
View Code
1 
object obj = 
10;
2 Console.WriteLine(obj.GetType());
3 
int result = (
int)obj;   
//
  int result=obj; Error:Connot implicitly convert type 'object' to 'int'

 

var是从c# 3.0 起添加的关键字,用于隐式类型化局部变量已经匿名类型。用var关键字声明变量时,编译时会根据初始化字符串来推断该变量的类型,并在运行时无法更改该变量的类型。vari经常和linq结合使用。

ExpandedBlockStart.gif
View Code
1 
var var1 = 
10;
2 Console.WriteLine(var1.GetType());
3 
int result = var1;
4 
//
 var1="test"; 在将string赋值给var1将会发生error,因为var类型确定了,就不能更改类型,所以只能把整数赋给它。

 

dynamic在某种程度上说依赖于object,因为dynamic类型在后台都是使用System.Object类型。但与object不同,dynamic类型在编译时不需要执行显示转换操作,它仅在运行时识别类型。

ExpandedBlockStart.gif
View Code
dynamic d = 
10;
Console.WriteLine(d.GetType()); 
//
output: System.Int32
int result = d;
d = 
"
test
";
Console.WriteLine(d.GetType());
//
 output :System.String

 

反射与dynamic

有时候我们不知道某对象的精确类型,但知道这个对象所拥有的某方法,为了调用这个方法,我们可以使用反射:

ExpandedBlockStart.gif
View Code
1 
object calc = GetCalculator();
2 Type calcType = calc.GetType();
3 
object res = calcType.InvokeMember(
"
Add
",BindingFlags.InvokeMethod, 
null
new 
object[] { 
10,
20 });
4 
int sum = Convert.ToInt32(res);

 

而使用dynamic,将会使代码更简洁,易读,易懂:

ExpandedBlockStart.gif
View Code
1 dynamic calc = GetCalculator();
2 
int sum = calc.Add(
10
20);

 

总结:dynamic可以是我们以更简洁的方式完成互操作性。同时c#还提供一些动态类,提供让我们自己对自己的类创建封装,如DynamicObject类。

 

 

 

 

转载地址:http://mkmjl.baihongyu.com/

你可能感兴趣的文章
rsyslog+loganalyzer简单日志分析
查看>>
Windows Server 2008 网络负载平衡群集
查看>>
走进云计算-带你一步步部署vsphere虚拟化平台--开山第一篇
查看>>
Linux服务器系统性能调优
查看>>
linux内存分配与brk(), sbrk()原理与应用
查看>>
Windows Phone应用商店中的应用程序已达4万
查看>>
SQLServer数据库设计规范
查看>>
《JQuery 能干点啥~》第三讲 html() 与 text()的取值比较
查看>>
51CTO两周年生日祝福
查看>>
Xen在centos5.x和centos6.x下安装方法
查看>>
【吾日三省吾身】2015.6.22-涅槃行动第三十五天
查看>>
Spring入门_04_注解注入
查看>>
LV扩展,LVM卸载
查看>>
我的友情链接
查看>>
str_replace() 函数
查看>>
CentOS 网络设置修改
查看>>
通达OA2013 数据库密码更改方法
查看>>
HDFS Balancer流程(下)
查看>>
将博客搬至CSDN
查看>>
ansible--inventory
查看>>