博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用
阅读量:5136 次
发布时间:2019-06-13

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

原文:

阅读目录:

一. 为什么是它们三个

二. 能够任意赋值的原因

三. dynamic的用法

四. 使用dynamic的注意事项

一. 为什么是它们三个?

拿这三者比较的原因是它们在使用的时候非常相似。你可以用它们声明的变量赋任何类型的值。

看看下面的示例:

var a = 1;object b = 1;dynamic c = 1;

 你还可以使用关键字为它们赋上更加复杂的类型

var a = new string[]{
"1"};object b = new string[]{
"1"};dynamic c = new string[]{
"1"};

二. 能够任意赋值的原因

 上面的例子中,看起来三者非常相似,但是背后的原理却是非常不同。

var是C# 3中引入的,其实它仅仅只是一个语法糖. var本身并不是一种类型, 其它两者object和dynamic是类型。

var声明的变量在赋值的那一刻,就已经决定了它是什么类型。

所以如果你这样使用,就会有编译错误:

var a = 1;a = "Test";

 

object之所以能够被赋值为任意类型的原因,其实都知道,因为所有的类型都派生自object. 所以它可以赋值为任何类型:

object a = 1;a = "Test";

 

那么dynamic呢?

它是C#引入的新类型,它的特点是申明为dynamic类型的变量,不是在编译时候确定实际类型的, 而是在运行时。

所以下面的代码是能够通过编译的,但是会在运行时报错:

dynamic a = "test";a++;

上面代码内部处理的过程是怎样的呢?

首先, dynamic类型赋值为字符串"test", 运行++操作的时候,.net会去寻找当前的赋值类型string中是否支持++操作,发现不支持,出现异常。

所以,如果这样修改一下,就可以让代码正常运行起来

dynamic a = "test";a = 1;a++;

三. dynamic的用法

1 直接使用该类型,可以非常方便的插入属性, 方法

static void Main(string[] args){    dynamic person = new System.Dynamic.ExpandoObject();    person.Name = "cary";    person.Age = 25;    person.ShowDescription = new Func
(() => person.Name + person.Age); Console.WriteLine(person.Name + person.Age + person.ShowDescription()); Console.ReadLine();}

枚举所有成员

foreach (var property in (IDictionary
)dynEO){ Console.WriteLine(property.Key + ": " + property.Value);}

3 简化反射

常用的处理反射的例子:

object calc = GetCalculator();Type calcType = calc.GetType();object res = calcType.InvokeMember( "Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });int sum = Convert.ToInt32(res);

使用dynamic之后:

dynamic calc = GetCalculator(); int sum = calc.Add(10, 20);

 

四,使用dynamic的注意事项

有了dynamic,.net就以及有了动态类型的优势,但是由于对于dynamic类型的所有操作,都是在运行时确定的,所有错误无法在编译时候出现,使用的时候,就需要非常小心。

因为dynamic是类型,所以如果函数接受的是确定类型的参数,是不能传入dynamic类型的,这样会有编译错误。比如:

public int Add(int a, int b){    return a + b;}dynamic test1 = 1;dynamic test2 = 2;Add(test1, test2);

下面是对上面的例子的修正,谢谢Alan@Net. 大家可以实验一下

    1. 2014-02-04 21:30
      为什么我copy你最后一个例子,并没有报错?
      回复引用删除
    2. [楼主] 2014-02-07 08:30
      Alan@Net
      应该是编译不通过,我待会试试
      修改删除
    3. [楼主] 2014-02-08 08:29
      Alan@Net
      是不会报错,对于普通的类型,int这样的,不会有问题。
      但是如果是对象类型,运行时会报错。

 

另外,在我们自己在写函数时,最好不要将dynamic类型作为函数的参数,这就像是使用object作为函数参数一样,会为程序的维护带来后续的麻烦。

没有人能够确定使用者传入的是什么,而且编译时候不会有问题。如果错误出现在运行时,就有可能是灾难。

posted on
2014-08-28 11:29 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/3941205.html

你可能感兴趣的文章
【概率】poj 2096:Collecting Bugs
查看>>
javascript 无限分类
查看>>
【自制插件】MMD4Maya
查看>>
解决linux服务器乱码
查看>>
mapbox.gl文字标注算法基本介绍
查看>>
【C++】异常简述(二):C++的异常处理机制
查看>>
web.config在哪里
查看>>
SQL Server 2000 版本支持的最大物理内存量
查看>>
spring IOC装配Bean(注解方式)
查看>>
FTP服务器的搭建和使用(centos7)
查看>>
[面试算法题]有序列表删除节点-leetcode学习之旅(4)
查看>>
SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
查看>>
MyEclipse搭建SSM框架(Spring+MyBatis+SpringMVC)
查看>>
kubernetes_book
查看>>
Linux下串口通信工具minicom的用法
查看>>
使用SWIG轻松编写Python扩展
查看>>
Redis 常用数据结构命令
查看>>
Tomcat之session解决方案
查看>>
缓冲区溢出漏洞实验
查看>>
Linux命令之bc - 浮点计算器、进制转换
查看>>