介绍

C# 4 引入了一个新类型 dynamic。 该类型是一种静态类型,但类型为 dynamic 的对象会跳过静态类型检查。 大多数情况下,该对象就像具有类型 object 一样。 在编译时,将假定类型化为 dynamic 的元素支持任何操作。 因此,不必考虑对象是从 COM API、从动态语言(例如 IronPython)、从 HTML 文档对象模型 (DOM)、从反射还是从程序中的其他位置获取自己的值。 但是,如果代码无效,则在运行时会捕获到错误。

var与dynamic对比

1、var编译时替换为实际类型,而dynamic实际是object类型。

一旦被编译,编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明,这看上去就好像我们在编码的时候是用实际类型进行申明的。而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。

2、智能感知。

以var声明的变量,支持“智能感知”,因为visual studion能推断出var类型的实际类型,而以dynamic声明的变量却不支持“智能感知”,因为编译器对其运行期的类型一无所知。对dynamic变量使用“智能感知”,会提示“此操作将在运行时解析”。

简单案例

编写一个hello world的测试程序,定义DynamicTest类型,并增加Welcome方法,其参数为name.

然后创建dynamic对象,调用Welcome方法。参数为空。

using System;

namespace DynamicSample
{
class Program
{
static void Main(string[] args)
{
dynamic obj = new DynamicTest();
obj.Welcome();
}
} class DynamicTest
{
public void Welcome(string name)
{
Console.WriteLine("Hello {0},welcome to dynamic world.",name);
}
}
}

看看发生什么事情呢,通过测试发现:

编译通过,没有任何异常。

运行时抛出异常,异常信息:

未处理Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
HResult=-
Message=“Welcome”方法没有采用“”个参数的重载
Source=Anonymously Hosted DynamicMethods Assembly
StackTrace:
在 CallSite.Target(Closure , CallSite , Object )
在 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
在 DynamicSample.Program.Main(String[] args) 位置 E:\Donet\C#\DynamicSample\DynamicSample\Program.cs:行号
在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:

修正后:

    class Program
{
static void Main(string[] args)
{
dynamic obj = new DynamicTest();
string name = "Tom";
obj.Welcome(name); Console.WriteLine("Input any key to exit.");
Console.ReadKey();
}
}

如果改为var,定义该对象,并调用方法,代码如下,编译器会报错:

            var v1 = new DynamicTest();
v1.Welcome();

错误信息:

    错误    CS7036    未提供与“DynamicTest.Welcome(string)”的必需形参“name”对应的实参    DynamicSample    Program.cs
错误 CS7036 There is no argument given that corresponds to the required formal parameter 'name' of 'DynamicTest.Welcome(string)' DynamicSample

dynamic应用范围

1、在声明中,作为属性、字段、索引器、参数、返回值或类型约束的类型,都可以使用dynamic。

2、在显式类型转换中,作为转换的目标类型。任何对象都可以隐式转为dynamic。

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

通过一个实例来具体说明:

    class DynamicUser
{
/// <summary>
/// 字段
/// </summary>
public dynamic userid; /// <summary>
/// 属性
/// </summary>
public dynamic UserName { get; set; } /// <summary>
/// 玩游戏
/// (dynamic可以作为参数、返回值等)
/// </summary>
/// <param name="game"></param>
/// <returns></returns>
public dynamic Play(dynamic game)
{
dynamic defaultGame = "Play Basketball."; dynamic secGame = "Play with mud."; if (game is int)
{
return defaultGame;
}
else
{
return secGame;
}
}
/// <summary>
/// 显式类型转换
/// </summary>
public void ConvertToDynamic(object obj)
{
dynamic d;
d = (dynamic)obj;
Console.WriteLine(d);
}
/// <summary>
/// 类型判定
/// (dynamic 可以使用is、as、typeof)
/// </summary>
public void TypeCheck()
{
int age = ;
Console.WriteLine("Age is Dynamic? {0}",age is dynamic); dynamic d = age as dynamic;
Console.WriteLine("Age:{0}",d); Console.WriteLine("List<dynamic>'s type is {0}",typeof(List<dynamic>));
} }

测试用例:

           DynamicUser user = new DynamicUser();
user.userid = ;
user.UserName = "Lucy";
user.ConvertToDynamic(user.userid);
user.ConvertToDynamic(user.UserName);
user.TypeCheck(); Console.WriteLine("Input any key to exit.");
Console.ReadKey();

应用

1、自动反射

2、COM组件互操作

3、混合编程,例如IronRuby和IronPython

4、处理Html DOM对象

5、还有一种应用,数据传输中格式转换,如:对象转json等,很方便

【C#复习总结】dynamic的更多相关文章

  1. @dynamic 模拟NSManagedObject类的内部实现,AFN的非常规用法

    @property和@synthesize复习 @property生成setter和getter的声明,同时生成属性对应的成员变量,并且前面加一个下划线_.如果将getter和setter的实现同时重 ...

  2. C#复习⑤

    C#复习⑤ 2016年6月19日 22:39 Main Inheritance 继承 1.继承的语法结构 class A { // base class int a; public A() {...} ...

  3. 【ASP.NET MVC】个人复习整理

    1.为 Action 标注 Attribute 限制访问 public class HomeController : Controller { [HttpPost] public ActionResu ...

  4. java 复习001

    java 复习001 比较随意的记录下我的java复习笔记 ArrayList 内存扩展方法 分配一片更大的内存空间,复制原有的数据到新的内存中,让引用指向新的内存地址 ArrayList在内存不够时 ...

  5. Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6471  Solved: 2697[Su ...

  6. C# 4.0 新特性-dynamic 【转】

    前段时间看过一些关于dynamic这个C#4中的新特性,看到有些朋友认为dynamic的弊大于利,如无法使用编译器智能提示,无法在编译时做静态类型检查,性能差等等.因此在这篇文章中我将就这些问题来对d ...

  7. SQL 复习笔记 MSSQL篇

    苦逼得很,一下就失业了,只有好好复习,迎接下一份工作 MSSQL篇:     1.数据库表分为临时表和永久表.临时表又分为全局临时表和局部临时表         全局临时表:表名以##开头.对系统当前 ...

  8. dynamic和匿名类和var的混合使用 没提示照样点

    using System;using System.Collections;using System.Collections.Generic;using System.Linq;using Syste ...

  9. ASP.NET复习笔记(1)

    今天是个好日子,伴着早上八点的朝阳,我背上书包,提上电脑,带上一根网线,风风火火的冲向教室,因为,我终于想好博客内容写啥了——这不是快期末了么,我就写复习,虽然有些课程还没讲完,但并不影响我做复习,正 ...

随机推荐

  1. Flutter 布局(一)- Container详解

    本文主要介绍Flutter中非常常见的Container,列举了一些实际例子介绍如何使用. 1. 简介 A convenience widget that combines common painti ...

  2. (后端)maven仓库

    仓库网址:http://mvnrepository.com/artifact/org.springframework/spring-core 可以去选择评分高的jar,复制: <!-- http ...

  3. PyCharm 在PyCharm中使用GitHub

    PyCharm是当前进行Python开发,尤其是Django开发最好的IDE,GitHub是程序员的圣地,几乎人人都在用,就不详细介绍两者了. 本文假设你对PyCharm和Github都有一定的了解, ...

  4. Hive内部表与外部表的区别

    1.未被external修饰的是内部表[managed table],被external修饰的为外部表[external table]. 2.内部表数据由Hive自身管理,外部表数据由HDFS管理. ...

  5. windows 获取用户的Sid的方法

    正常获取: whoami /user 如果要获取其他用户的SID就显得力不从心了,我们可以使用微软提供的系统工具 Sysinternals Suite 下载地址:https://docs.micros ...

  6. Json.net日期格式化设置

    Json.net默认的时间格式化后带T,不符合一般的业务要求,重新设置JSON.NET的默认日期格式化方式,代码如下: /// <summary> /// Json.net默认转换设置 / ...

  7. python 制作一对一聊天

    用到的参考资料 https://blog.csdn.net/jia666666/article/details/81624550 https://blog.csdn.net/jia666666/art ...

  8. AndroidStudio2.2.x以上使用cMake编译调用底层c生成依赖库

    最近使用AndroidStudio的最新ndk编译方式cMake来编译底层cpp文件,由于之前没有接触过cMake语法,先附上官方学习文档地址:https://developer.android.co ...

  9. JavaScript函数式编程

        一段糟糕透顶的海鸥seagulls程序   鸟群合并conjoin则变成了一个更大的鸟群,繁殖breed则增加了鸟群的数量,增加的数量就是它们繁殖出来的海鸥的数量 //Flock 群 var ...

  10. AttributeError: 'list' object has no attribute 'keys'

    #encoding=utf-8 import os result = {} if os.path.exists("test.txt"): day_file = open(" ...