C#编程总结 dynamic(转)

介绍

Visual C# 2010 引入了一个新类型 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=-2146233088
  Message=“Welcome”方法没有采用“0”个参数的重载
  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:行号 13
       在 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    15
    错误    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 = 20;
            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 = 123;
            user.UserName = "Lucy";
            user.ConvertToDynamic(user.userid);
            user.ConvertToDynamic(user.UserName);
            user.TypeCheck();

            Console.WriteLine("Input any key to exit.");
            Console.ReadKey();

测试结果:

dynamic的执行效率

关于dynamic的效率问题,这里暂不展开,后续专门来讨论...

应用

1、自动反射

2、COM组件互操作

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

4、处理Html DOM对象

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

时间: 2024-10-11 18:14:55

C#编程总结 dynamic(转)的相关文章

C#与.Net Framework的各种版本和联系

转载:http://www.tuicool.com/articles/3Enu2a C#语言 C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新成果.C#看起来与Java有着惊人的相似:它包括了诸如单一继承.接口.与Java几乎同样的语法和编译成中间代码再运行的过程.但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对

C#编程总结(十四)dynamic

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

Dynamic编程

Dynamic Binding 动态绑定 Binding:解析Type,member,operation的过程. 动态绑定将Binding从编译时延迟到运行时进行. 场景 编译时,程序员知道特定的function,member,operation的存在,而Compiler不知道. 1 dynamic d = GetSomeObject(); 2 d.Quack(); dynamic_obj 期望在运行时,d类型会含有Quack().所以,编译器推迟d和Quack()的绑定到运行时. dynami

C#高级编程七十天----dynamic类型

dynamic类型 C#新增了dynamic关键字,正是因为这一个小小的关键字,C#像前迈进了一大步. dynamic是一个类型关键,声明为dynamic的类型与"静态类型"(这里的静态是指编译时确定的类型,例如int,double类型)相比最大的特定它是"动态类型",它会在运行时尝试调用方法,这些方法的存在与否不是编译时期检查的,而是在运行时查找,如果方法存在并且参数正确,会正确调用,否则会抛出异常. 案例: dynamic d = Console.Out; dy

编程内功修炼 - 算法

编程内功讲什么? 主要讲解以下算法: 分治法 堆排序 二叉树 动态规划 贪心算法 图 算法的作用: 算法解决了哪些问题? 互联网信息的访问检测,海量数据的管理 在一个交通图中,寻找最近的路 人类基因工程,dna有10万个基因,处理这些基因序列需要复杂的算法支持 上面的算法是我们没有接触到,或者是封装到底层的东西,那么作为程序员,在日常编码过程中会在什么地方使用算法呢? 在你利用代码去编写程序,去解决问题的时候,其实这些编码过程都可以总结成一个算法,只是有些算法看起来比较普遍比较一般,偶尔我们也会

GPU渲染管线与可编程着色器

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/71978861 这篇文章是解析计算机图形学界"九阴真经总纲"一般存在的<Real-Time Rendering 3rd>系列文章的第三篇.将带来RTR3第三章内容"Chapter 3 The Graphics Processing Unit 图形处理器"的总结.概括与提炼. 这章的主要内容是介绍G

370 门免费编程与计算机科学在线课程

简评:这篇文章为大家整理出 370 门精选的免费高质量编程计算机科学类的课程(涵盖程序语言.人工智能.深度学习与机器学习等热门话题).这370 门课程是从 Class Central数据库里面的 7000 门课程挑选出来的,每个课程的 Rating(评价)也是由该网站上获取下来的平均值. 370 门课程里面根据难易程度被分为: 入门 中级 进阶 所收录的大部分教程都已经更新完毕了,你可以按照自己的节奏(Self Paced)随时观看学习,有小部分教程还在持续更新至中,当然了,它们全都是免费的!

Dynamic dispatch

Dynamic dispatch动态调度.动态分发 In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It is commonly employed in, and considered a prime characteristic of

Win32编程API 基础篇 -- 1.入门指南 根据英文教程翻译

入门指南 本教程是关于什么的 本教程的目的是向你介绍使用win32 API编写程序的基础知识(和通用的写法).使用的语言是C,但大多数C++编译器也能成功编译,事实上,教程中的绝大多数内容都适用于任何可以连接API的语言,包括Java.Assembly和Visual Basic:我不会向你呈现任何跟这些语言相关的代码,这需要你在本教程的指导下自己去完成,有一些人在本API的基础上使用其他语言进行编程取得了相当的成功. 本教程不会教你C语言,也不会告诉你怎样去运行你特定的编译器(Borland C