阅读目录:

一. 为什么是它们三个

二. 能够任意赋值的原因

三. dynamic的用法

四. 使用dynamic的注意事项

一. 为什么是它们三个?

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

看看下面的示例:

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

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

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

二. 能够任意赋值的原因

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

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

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

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

var a = ;
a = "Test";

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

object a = ;
a = "Test";

那么dynamic呢?

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

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

dynamic a = "test";
a++;

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

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

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

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

三. dynamic的用法

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

static void Main(string[] args)
{
dynamic person = new System.Dynamic.ExpandoObject();
person.Name = "cary";
person.Age = ;
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[] { , });
int sum = Convert.ToInt32(res);

使用dynamic之后:

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

四,使用dynamic的注意事项

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

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

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

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

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

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

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

理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用的更多相关文章

  1. [转]理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用

    阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 一. 为什么是它们三个? 拿这三者比较的原因是它们在使用的时候非常相似.你 ...

  2. var, object, dynamic的区别以及dynamic的使用

    var, object, dynamic的区别以及dynamic的使用 理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用 2013-06- ...

  3. (转载)【C#4.0】dynamic和var及object

    dynamic a = 10;a = a + 10;Console.WriteLine(a.GetType()); 此段代码会输出 System.Int32,第二行不需要类型转换,因为在运行时识别类型 ...

  4. var, object, dynamic的区别以及使用(转载)

    var, object, dynamic的区别以及使用 阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 拿这三者比较的原因 ...

  5. var, object, dynamic的区别以及使用

    var, object, dynamic的区别以及使用 阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 拿这三者比较的原因 ...

  6. 【C# 基础概念】C# 4 dynamic - var, object, dynamic的区别以及dynamic的使用

    阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 一. 为什么是它们三个? 拿这三者比较的原因是它们在使用的时候非常相似.你 ...

  7. dynamic和var的区别

    1.var声明一个局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型. 2.var只能用于声明方法内部的局部变量,而dynamic可用于局部变量,字段,参数. 3.表达式不能转型为 ...

  8. 弱类型dynamic与var

    dynamic与var都可代替任何类型 var关键字是C# 3.0开始新增的特性,称为推断类型. 1.必须在定义时初始化 2.一但初始化完成就不能再给变量赋与初始化值类型不同的值 3.var要求是局部 ...

  9. dynamic与var

    dynamic与var示例 var是一种语法省略写法,编译器会根据上下文推断出正确的类型. , , , , , , , }; foreach (var item in scores) { Consol ...

随机推荐

  1. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q105-Q108)

    Question  105   You are designing a SharePoint 2010 application that contains a single list named Us ...

  2. AIDL使用解析

    简书本文地址:点击跳转到简书查看 之前面试的时候被问到这个问题,然而当时只有一个大致的印象,随GG,于是我就重新整理的一下.这里大力推荐<Android开发艺术探索>这本书,写的太好了! ...

  3. h5曲线滑动确认

    h5项目需根据几条弯曲的线条让用户进行曲线式滑动,滑动时需实时响应某些样式,于是就有了下面这个实例.(可自定义多个子对象大小分别放在线条各处,以增加曲线滑动确认精度.) <!doctype ht ...

  4. 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接(转)

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

  5. 利用 filter 机制 给 静态资源 url 加上时间戳,来防止js和css文件的缓存,利于开发调试

    直接上代码: public class WeiXinFilter implements Filter{ private static Logger logger = LoggerFactory.get ...

  6. SQL Server 2008 R2——根据数据查找表名和字段名 根据脏数据定位表和字段

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  7. C++STL - 类模板

    类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板   1.定义 template<typename 类型形参1, typename 类型形参2,...&g ...

  8. centos 6.x安装rvm 配置 Ruby开发环境

    rvm是ruby的版本管理工具  还可对ruby进行 安装 卸载 等 1.安装 curl #  sudo yum install  curl #  curl -L  get.rvm.io | bash ...

  9. 【转】iframe和父页,window.open打开页面之间的引用

    [转]iframe和父页,window.open打开页面之间的引用 iframe和父页,window.open打开页面和被打开页面之间的关系可以通过下面的对象获取到 1)通过iframe加载的,在if ...

  10. Java Generics and Collections-2.1

    2.1 子类化以及替换原理 为什么List<Integer> 不是List<Number> 的子类? 首先看下面的代码,这段代码是编译不过的 package java_gene ...