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

原文:理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用

阅读目录:

一. 为什么是它们三个

二. 能够任意赋值的原因

三. 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. 大家可以实验一下

    1. #15楼 Alan@Net   2014-02-04 21:30

      为什么我copy你最后一个例子,并没有报错?

      支持(0)反对(0)

      回复引用删除

    2. #16楼[楼主] JustRun   2014-02-07 08:30

      @Alan@Net
      应该是编译不通过,我待会试试

      支持(0)反对(0)

      修改删除

    3. #17楼[楼主] JustRun   2014-02-08 08:29

      @Alan@Net
      是不会报错,对于普通的类型,int这样的,不会有问题。
      但是如果是对象类型,运行时会报错。

 

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

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

时间: 2024-08-04 03:49:46

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

深入理解JavaScript中的对象复制(Object Clone)_基础知识

JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b.k2 = 4; 如果只想改变b而保持a不变,就需要对对象a进行复制. 用jQuery进行对象复制 在可以使用jQuery的情况下,jQuery自带的extend方法可以用来实现对象的复制. a = {k1:1, k2:2, k3:3}; b = {}; $.extend(b,a); 自定义clone

深入理解关于javascript中apply()和call()方法的区别_javascript技巧

如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语言过程中遇到这种感觉,那么就从现在形始,请放下的您的"偏见",因为这对您来说绝对是一片新大陆,让JavaScrip慢慢融化以前一套凝固的编程意识,注入新的生机! 好,言归正传,先理解JavaScrtipt动态变换运行时上下文特性,这种特性主要就体现在apply, call两个方法的运用上.

javascript-在函数中写 this.xx=function 和 var xx =function() 的区别

问题描述 在函数中写 this.xx=function 和 var xx =function() 的区别 亲问各位一个问题 JS代码如下 function Test(){ this.add = function(){ alert(1); } this.modAdd = function(){ this.add(); add(); // 以上两种均无法调用到ADD方法 // Uncaught TypeError: this.add is not a function } } var test =

equals(Object) 与 == 的区别

在比较对象时候,常常用到"=="和"equals(Object)".它们常常让初学者感到疑惑.下面先看一个例子 public class Example1{ public static void main(String[] args) { String s1=new String("abc"); String s2=new String("abc"); // s1=s2; System.out.println("用

快速理解聚合根、实体、值对象的区别和联系

深入理解mysql SET NAMES和mysql(i)_set_charset的区别_Mysql

说到, 尽量使用mysqli_set_charset(mysqli:set_charset)而不是"SET NAMES", 当然, 这个内容在PHP手册中也有叙及, 但是却没有解释为什么. 最近有好几个朋友问我这个问题, 到底为什么? 问的人多了, 我也就觉得可以写篇blog, 专门介绍下这部分的内容了. 首先, 很多人都不知道"SET NAMES"到底是做了什么, 我之前的文章深入MySQL字符集设置中, 曾经介绍过character_set_client/cha

深入理解require与require_once与include以及include_once的区别_php技巧

PHP具有快速.可靠.跨平台应用.源代码开放等特点,使得PHP成为最受欢迎的服务器端Script语言之一.我根据自己在工作中体会到的,向大家介绍PHP使用的心得,希望对大家有所帮助. 利用PHP的Include files维护你的网站 不管你所开发的网站的规模是大是小,你都应该要认识到重复使用程序代码的重要性,不论你重复使用的是 PHP 程序或者是 HTML 原始码.举个例子来说,网站页尾的版权宣告至少每年都得修改一次,如果你的网站有许多个页面,该怎么办呢?动手一个一个修改这些页面肯定是一件头痛

dynamic、object、var 之间的区别

dynamic .net 4.0  动态类型   ExpandoObject 应用   dynamic Customer = new ExpandoObject(); Customer.Name = "Name001"; Customer.Age = 12; Console.WriteLine(Customer.Name + Customer.Age);          可实现不同类型之间的连接   static T Add<T>(T t1, T t2) { dynami

C#常用算法:Dynamic Object

Dynamic Object包含在.Net4.0中,该对象可以允许我们在运行时中改变它的类型,有了这种万金油还有什么问题是我们不能解决的呢?我们来看看它的几个使用例子吧: Var类型和Dynamic类型 public static void TestDynamicObject() { //var object and dynamic object var varObj = "this is a var object"; dynamic dyObj = "this is a d