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架构是非常有帮助的。

var与dynamic的更多相关文章

  1. var和dynamic的区别及如何正确使用dynamic ?

    C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,他们都可以申明动态类型的变量,但是本质上他们还是有不少区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的值, ...

  2. C#中var和dynamic

    var与dynamic这两个关键字,只是看起来很相似,仅此而已!var表示“变量的类型是在编译时决定的”,但是dynamic表 示“变量的类型是在运行时决定的”.因此,dynamic与var具有截然不 ...

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

    C#中关键字var和dynamic的区别如下: 1.var申明的变量必须初始化,dynamic申明的变量无需初始化. 2.var关键字只能在方法内部申明局部变量,dynamic关键字可用于局部变量,字 ...

  4. C#4.0中var和dynamic的区别

    1. var表示“变量的类型是在编译时决定的”, var让你在初始化变量时少输入一些字,编译器会根据右值来推断出变量的类型, var只能用于局部变量的定义,你不能把类的属性定义成 var,也不能把方法 ...

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

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

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

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

  7. C#中的var和dynamic

    在理解var和dynamic关键字之前,让我们先了解一下编程语言的类别. C#中有两类编程语言: 静态类型语言类别 动态语言类别 静态类型语言 静态类型语言也被称为强类型语言.所谓强类型语言,通俗的讲 ...

  8. 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)

    一. 语法糖简介   语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方 ...

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

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

随机推荐

  1. OK335xS GPMC nand device register hacking

    /********************************************************************************* * OK335xS GPMC na ...

  2. Android shell command execute Demo

    package com.android.utils; import java.io.File; import java.io.IOException; import java.io.InputStre ...

  3. 【linux】如何退出shell终端

    退出shell终端: exit + 回车即可 清除当前屏幕信息 clear 不过clear只是将之前的命令向上隐藏啦...

  4. 【linux】wifi不能使用的问题

    Worked solution (Requirements: kernel >=4.11) : Download driver directory from this repo:https:// ...

  5. TX2-start 6 CPU kernel-开启高功耗模式

    1.TX2简介 Jetson TX2是由一个GPU和一个CPU集群组成.CPU集群由双核denver2处理器和四核ARM Cortex-A57组成,通过高性能互连架构连接.拥有6个CPU核心和一个GP ...

  6. EasyTouch基本用法

    EasyTouch基本用法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 hierarchy (层次面 ...

  7. IO练习--按字节截取字符串

    * 在Java中字符串“abcd”和字符串“ab你好”都是4个字符, * 但是字节数不同,因为GBK中一个汉字占两个字节 * 定义一个方法用来按字节数截取字符串. * 如:对于“ab你好”,取3个字节 ...

  8. HDU 4548:美素数

    Problem Description 小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识. 问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素 ...

  9. 生成html报告并整合自动发动邮件功能

    from HTMLTestRunner import HTMLTestRunnerfrom email.mime.text import MIMETextfrom email.header impor ...

  10. 对比dfs与bfs的存储机制以及bfs与队列的关系

    dfs由于是利用递归进行遍历,所以每种情况在时空上不会出现冲突,所以可以利用数组将每种情况的各个元素的值进行存储(即存储当前位) 而bfs由于并不是利用递归,不能将每种情况的值进行不冲突地存储,但由于 ...