浅谈隐式类型var和动态类型dynamic以及MVC特性ViewBag

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

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

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

 

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

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

  var这个类型是通过编译器确定的(即在编译时,编译器会根据这个变量的值或引用的对象类型来决定这个变量的类型),但要注意一旦这个变量的类型确定了之后就不可在更改,同时var型变量在申明时必须初始化。如下代码就不做详细的举例了:

//下面的两个 i 声明在功能上是等效的
var
i = 10; // implicitly typed(隐式申明) int i = 10; //explicitly typed(显示申明)
var i = 1;    //i为int型 , 等价于 int i = 1;
i = 1.0//报错,1.0为double型
var i = 1;    //正确

var i; 
i = 1;    //错误

2.dynamic

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

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

//在显式类型转换中,作为转换的目标类型,以及dynamic一些常见的用法。
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);

    // 字段
    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;
        }
    }
}

3.dynamic与ViewBag

  ViewBag是一个dynamic类型的属性,所以编译器不会对它进行检查,所以我们可以自定义属性,这里就不做详细的代码示例了。

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

 

posted on 2018-06-05 15:34  马元昊  阅读(660)  评论(0编辑  收藏  举报