var与dynamic

var与dynamic

  如果你用MVC写过程序,那么你应该知道ViewBag这个用于前后台的数据传递工具,那么你是否对ViewBag的用法感到过疑惑呢?

ViewBag.Mode1l=new object();
ViewBag.Model2=new object();
ViewBag.Model3=new object();
......

  我们知道,在使用对象属性的时候要先申明(即这个对象的类中已经定义了这个属性)才能使用(此时VS的自动提示能弹出此类的所有属性),然而使用ViewBag时你会发现 ViewBab. 之后不会弹出任何属性(除非前面已经添加了属性),而且我们可以自己随便写一个属性,却可以正确运行。而这都是归功于dynamic这个属性。

1.在讲dynamic之前,先来回顾一下var这个类型。

  从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型 var。 隐式类型的本地变量是强类型变量(就好像您已经声明该类型一样),但由编译器确定类型。 下面的两个 i 声明在功能上是等效的:

var i = 10; // implicitly typed(隐式申明)
int i = 10; //explicitly typed(显示申明)

  var这个类型是通过编译器确定的(即在编译时,编译器会根据这个变量的值或引用的对象类型来决定这个变量的类型),但要注意一旦这个变量的类型确定了之后就不可在更改。

var i = 1;    //i为int型 , 等价于 int i = 1;
i = 1.0;    //报错,1.0为double型

  注意,var型变量在申明时必须初始化,如下:

var i = 1;    //正确

var i; 
i = 1;    //错误

2.var用法举例:

// 允许但不需要使用var,因为可以将查询结果的类型显示的申明为IEnumerable<string>
string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
var wordQuery = from word in words
                where word[0] == ‘g‘
                select word;

// 因为元素类型为string类型,不是匿名类型,所以var是非必需的
foreach (string s in wordQuery)
{
    Console.WriteLine(s);
}

//表达式中必须使用 var,因为结果是一个匿名类型集合,而该类型的名称只有编译器本身可以访问
var custQuery = from cust in customers
                where cust.City == "Phoenix"
                select new { cust.Name, cust.Phone };

//foreach 迭代变量 item 也必须转换为隐式类型,因为custQuery为匿名集合
foreach (var item in custQuery)
{
    Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
}

3.dynamic

  在通过 dynamic 类型实现的操作中,该类型的作用是绕过编译时类型检查, 改为在运行时解析这些操作。 dynamic 类型简化了对 COM API(例如 Office Automation API)、动态 API(例如 IronPython 库)和 HTML 文档对象模型 (DOM) 的访问。

  在大多数情况下,dynamic 类型与 object 类型的行为是一样的。 但是,不会用编译器对包含 dynamic 类型表达式的操作进行解析或类型检查。 编译器将有关该操作信息打包在一起,并且该信息以后用于计算运行时操作。 在此过程中,类型 dynamic 的变量会编译到类型 object 的变量中。 因此,类型 dynamic 只在编译时存在,在运行时则不存在。

class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;

        dyn = dyn + 3;    //编译可以通过,dynamic可以绕过编译器
        obj = obj + 3;    //报错,编译无法通过

        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

//输出结果
System.Int32
System.Int32     

4.dynamic一些常见的用法

  (1)在声明中,作为属性、字段、索引器、参数、返回值或类型约束的类型。

class ExampleClass
{
    // 字段
    static dynamic field;

    // 属性
    dynamic prop { get; set; }

    //返回值与参数
    public dynamic exampleMethod(dynamic d)
    {
        dynamic local = "Local variable";
        int two = 2;

        if (d is int)
        {
            return local;
        }
        else
        {
            return two;
        }
    }
}

  (2)在显式类型转换中,作为转换的目标类型。

static void convertToDynamic()
{
    dynamic d;
    int i = 20;
    d = (dynamic)i;
    Console.WriteLine(d);

    string s = "Example string.";
    d = (dynamic)s;
    Console.WriteLine(d);

    DateTime dt = DateTime.Today;
    d = (dynamic)dt;
    Console.WriteLine(d);

}
// Results:
// 20
// Example string.
// 2/17/2009 9:12:00 AM

  (3)在以类型充当值(如 is 运算符或 as 运算符右侧)或者作为 typeof 的参数成为构造类型的一部分的任何上下文中。

int i = 8;
dynamic d;

if (someVar is dynamic) { }

d = i as dynamic;

Console.WriteLine(typeof(List<dynamic>));
//Console.WriteLine(typeof(dynamic));  //编译错误

5.dynamic与ViewBab

  ViewBab是一个dynamic类型的属性,所以编译器不会对它进行检查,所以我们可以自定义属性。我们也可以通过ExpandoObject() 这个类来实现我们自己的ViewBab,看下面示例:

public class Program
{
      public static void Main(string[] args)
      {
          dynamic model = new ExpandoObject();    //在运行时,model 会转化为 ExpandoObject() 的一个实例
          model.Index = 0;                        //ExpandoObject() 有一个事件 PropertyChanged,运行时动态触发这个事件,
          model.Number = 0;                       //然后将Index与Number这个两个属性添加到类中
          Console.WriteLine(model.Index);
          Console.WriteLine(model.Number);
          Console.ReadKey();
      }
}

  也许你会觉得dynamic用到的不多,所以不必深入理解,但等到你真正遇到它时,将会吃大亏。正如上面讲的那样,它在COM API 、 动态API 、HTML对象模型的操作上有重要作用,通过它,可以简化操作,但同时它也容易让人迷糊(它所指向的究竟是什么样的对象类型),因为简化通常意味着隐藏,它将复杂的后台实现封装并开放见简单的接口给我们使用,这样简化了我们的操作,却然我们更容易迷惑,我们不知道它为什么要这样做,只知道可以这样做,使得我们在很多问题上无法深入挖掘。在网站开发中,深入理解dynamic,有利于我们深入到框架内部去,对我们学习.Net架构是非常有帮助的。

时间: 2024-10-08 10:40:56

var与dynamic的相关文章

.net基础扫盲--可变类型(var,dynamic)

之所以要谈及var和dynamic,是因为在使用EF框架和使用MVC的时候,会很频繁的用到他们,所以不得不提他们,以便在接触EF和MVC的时候能够很好的理解和熟练的应用. 先简单说一下var,虽被称作是可变类型,但他并不是一种若类型,只不过他是通过程序推断来确定类型的. 我们可以这么写: static void Main(string[] args) { var i = 10; //经过程序的推断,i最终被推断为 int整型 var j = "10";//同样,经程序推断为字符型 Co

C#中var和dynamic

var与dynamic这两个关键字,只是看起来很相似,仅此而已!var表示"变量的类型是在编译时决定的",但是dynamic表 示"变量的类型是在运行时决定的".因此,dynamic与var具有截然不同的含义.var让 你在初始化变量时少输入一些字,编译器会根据右值来推断出变量的类型.dynamic更厉害,它告诉编译器,根本就别理究竟是啥类型,运行 时再推断不迟.var只能用于局部变量的定义,你不能把类的属性定义成 var,也不能把方法的返回值类型或者是参 数类型定

简述C#中关键字var和dynamic的区别

C#中关键字var和dynamic的区别如下: 1.var申明的变量必须初始化,dynamic申明的变量无需初始化. 2.var关键字只能在方法内部申明局部变量,dynamic关键字可用于局部变量,字段,参数. 3.表达式不能转型为var,但可以转型为dynamic. 4.用var关键字声明变量时,编译时会根据初始化值来推断该变量的类型,用dynamic关键字声明变量时,编译的时候不执行类型检查,仅在运行时识别对象的类型. 注:参考<CLR via C# 4>

理解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; 你还可以使用关键字为它们赋上更加复杂的类型 v

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

var, object, dynamic的区别以及使用 阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 拿这三者比较的原因是它们在使用的时候非常相似.你可以用它 们声明的变量赋任何类型的值. 看看下面的示例: var a = 1; object b = 1; dynamic c = 1; 上面的例子中,看起来三者非常相似,但是背后的原理却是非常 不同. var是C# 3中引入的,其实它仅仅只是一个语法. var本身并不

C#中 Var 和 dynamic 整理介绍

常有人会拿var这个关键字来和dynamic做比较.实际上,var和dynamic完全是两个概念,根本不应该放在一起做比较.var实际上是编译期抛给我们的"语法糖",一旦被编译,编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明,这看上去就好像我们在编码的时候是用实际类型进行申明的.而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期. 以var声明的变量

Var与Dynamic的区别

1.var与dynamic的区别   C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,但其实它们是有本质的区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的值,而dynamic则可以不提供,它是在运行时才确定类型. 1 static void Main(string[] args) 2 { 3 //var 在编译阶段已经确定类型 4 var number = 3; 5 6 //dynamic在编译期间不进行任何的类型检查,而是将类型检查放到了运行期 7

var object dynamic的区别

一.var var本身不是一种类型,只是一种语法糖:var声明的变量在赋值的时候即已决定其变量类型,编译时会进行校验. 二.object object是所以类型的基类,故可以赋任何类型的值. 三.dynamic dynamic是在运行时去确定实际类型,而在编译时是不进行校验的. 参考资料: http://www.cnblogs.com/sntetwt/p/3530937.html

MVC 之var与dynamic

如果你用MVC写过程序,那么你应该知道ViewBag这个用于前后台的数据传递工具,那么你是否对ViewBag的用法感到过疑惑呢? ViewBag.Mode1l=new object(); ViewBag.Model2=new object(); ViewBag.Model3=new object(); ...... 我们知道,在使用对象属性的时候要先申明(即这个对象的类中已经定义了这个属性)才能使用(此时VS的自动提示能弹出此类的所有属性),然而使用ViewBag时你会发现 ViewBab. 之