阅读目录:

一. 为什么是它们三个

二. 能够任意赋值的原因

三. 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<string>(() => person.Name + person.Age); Console.WriteLine(person.Name + person.Age + person.ShowDescription());
Console.ReadLine();
}

枚举所有成员

foreach (var property in (IDictionary<String, Object>)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. 大家可以实验一下

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

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

最新文章

  1. jquery实现简单的Tab切换菜单
  2. android 72 确定取消对话框,单选对话框,多选对话框
  3. TWRP-recovery中文界面安装方法[转]
  4. J2SE知识点摘记(十六)
  5. [置顶] java 枚举
  6. C#设计模式之十七观察者模式(Observer Pattern)【行为型】
  7. scrapy初试水 day02(正则提取)
  8. 面试题中遇到的算法与js技巧
  9. spring boot 系列之三:spring boot 整合JdbcTemplate
  10. Pandas的可视化操作(利用pandas得到图表)
  11. vue中插入Echarts示例(菜鸟记录)
  12. OkHttp封装之后使用
  13. InnoDB中锁的模式,锁的查看,算法
  14. 【Python】进程-锁(1)
  15. VR/AR 科技了解
  16. 使用windowAnimations定义Activity及Dialog的进入退出效果
  17. Python面向对象:继承和多态
  18. .NET数据挖掘与机器学习开源框架
  19. JS进阶系列之this
  20. ubuntu(14.4) 安装phpmyadmin

热门文章

  1. DEEP LEARNING WITH PYTORCH: A 60 MINUTE BLITZ | TORCH.AUTOGRAD
  2. Android开发----Button组件的使用与练习
  3. JVM专题2: JVM内存结构
  4. django之百度Ueditor富文本编辑器后台集成
  5. Luogu_P1613跑路
  6. Codeforces Round #741 (Div. 2)
  7. SharePoint Online 为Modern Page添加脚本
  8. Argo 安装和 workflow 实例配置文件解析
  9. BootStrap基础入门概述总结
  10. String类为什么可以直接赋值