编制程序总计,动态目的
分类:计算机编程

dynamic是FrameWork4.0的新特色。dynamic的现身让C#具备了弱语言类型的风味。编写翻译器在编写翻译的时候不再对项目举行检查,编译期暗中同意dynamic对象扶植您想要的别样本性。举例,纵然你对GetDynamicObject方法再次来到的对象胸无点墨,你也得以像如下那样实行代码的调用,编写翻译器不会报错:

C#编制程序计算(十一卡塔尔国dynamic

让我们飞速看看object关键字先。小编不会对它讲太多,因为它在C#1.0就曾经有了。这几个器重字未有越来越多东西除了作为System.Object的火速格局,System.Object是C#类档次的根类型。(然则,正如EricLippert在她博客中建议,毫不一切类型都一而再源于object[中][英]卡塔尔国那是多少个强硬的建制,那样你差十分的少能够分配任何实例值到此类型。

dynamic dynamicObject = GetDynamicObject();
Console.WriteLine(dynamicObject.Name);
Console.WriteLine(dynamicObject.SampleMethod());

介绍

Visual C# 二〇〇八 引入了三个新类型 dynamic。 该类型是生龙活虎种静态类型,但品种为 dynamic 的靶子会跳过静态类型检查。 大好多情景下,该对象就如具有类型 object 相近。 在编写翻译时,将假定类型化为 dynamic 的因素支持其余操作。 由此,您不要思索对象是从 COM API、从动态语言(譬喻 IronPython卡塔尔、从 HTML 文书档案对象模型 (DOM)、从反射依旧从程序中的别的岗位获取本人的值。 可是,假若代码无效,则在运作时会捕获到错误。

 

那是个小例子用来演示使用object关键字的功利和主题素材。

dynamic与var关键字本质分化

var只好用作一些变量,无法用于字段,参数;注脚的还要必得伊始化;初阶化时类型就曾经鲜明了,而且不可能再被赋值不可能开展隐式类型转变的档期的顺序的数据。

var实际上是编写翻译期抛给大家的“语法糖”,一旦被编写翻译,编写翻译期会自动相配var 变量的实际类型,并用实际类型来替换该变量的表明,那看起来就临近大家在编码的时候是用实际类型举行表明的。

dynamic可用来项指标字段,方法参数,方法再次回到值,可用来泛型的连串参数等;能够赋值给或被赋值任何项目而且没有供给显式的要挟类型调换,因为那么些是运转时举办的,那要得益于dynamic类型的动态天性。

dynamic被编写翻译后,实际是三个object类型,只但是编写翻译器会对dynamic类型进行出格管理,让它在编译期间不进行别的的花色检查,而是将项目检查放到了运营期。

从visual studio的编辑器窗口就能够看出来。以var评释的变量,扶助“智能感知”,因为visual studion能估计出var类型的其实类型,而以dynamic注明的变量却不扶持“智能感知”,因为编写翻译器对其运营期的花色胸无点墨。对dynamic变量使用“智能感知”,会提示“此操作就要运营时深入分析”。

var与dynamic对比

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

万风姿洒脱被编写翻译,编写翻译期会自动相配var 变量的实际上类型,并用实际类型来替换该变量的发明,那看起来就就如大家在编码的时候是用实际类型实行表达的。而dynamic被编写翻译后,实际是叁个object类型,只不过编写翻译器会对dynamic类型实行极其管理,让它在编写翻译时期不开展其余的门类检查,而是将品种检查放到了运维期。

2、智能感知。

以var证明的变量,支持“智能感知”,因为visual studion能估计出var类型的实际上类型,而以dynamic表明的变量却不援助“智能感知”,因为编写翻译器对其运转期的花色一无所知。对dynamic变量使用“智能感知”,会唤醒“此操作将要运行时深入分析”。

 

object obj = 10;

Console.WriteLine(obj.GetType());

// 输出 System.Int32 因为

// 那是那些指标里积存的值的品类。

// 多个编写翻译错误, 因为 

// 在编写翻译时obj的体系是System.Object。

// obj = obj 10;

// 你须求显式转变obj到希望的档案的次序。

obj = (int)obj 10;

// 但是, 那样并不代表您真的安全。 

// 你大概调换来贰个荒唐的品种 

// 而编写翻译器并不会意识。 

// 这里您会在运作时拿到八个卓殊, 

// 因为obj是int类型,不是string类型。

// obj = (string)obj 10;

// 假若您将其更动成二个谬误的数值类型, 

// 你也会得到贰个运作时相当 

// 尽管有隐式调换的语法在此。

// obj = (double)obj 10;

类型转变

Dynamic类型的实例和任何门类的实例间的转变是很简单的,开荒职员能够很平价地在dyanmic和非dynamic行为间切换。任何实例都能隐式转变为dynamic类型实例,见下边包车型地铁例子:

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Conversely, an implicit conversion can be dynamically applied to any expression of type dynamic.
反之相通,类型为dynamic的此外表明式也能够隐式变换为其余品类。

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

大致案例

编写制定四个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:DonetC#DynamicSampleDynamicSampleProgram.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();
        }
    }

运维结果:

图片 1

 

比如改为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    

 

你能够旁观,就算obj存款和储蓄一个int值,若无改换,编写翻译器依旧不会让您实践其它数学操作。它看起来好疑似帮忙你明确是否你真有三个int类型,但它不是。你能够转变来三个一心两样的花色但编写翻译器却检查不出。结果就是,你得到叁个运作时非常。

方式中含有dynamic类型参数的重载难点

生机勃勃经调用三个办法是传递了dynamic类型的指标,只怕被调用的靶子是dynamic类型的,那么重载的决断是发出在运作时而不是编写翻译时。
动态语言运维时(dynamic language runtime DL昂Cora卡塔尔国动态语言运转时是.NET Framework 4 Beta 第11中学的后生可畏组新的API,它提供了对c#中dynamic类型的支撑,也兑现了像IronPython和IronRuby之类的动态程序设计语言。

dynamic应用范围

1、在注脚中,作为质量、字段、索引器、参数、重返值或项目约束的档期的顺序,都能够应用dynamic。

2、在显式类型转换中,作为调换的靶子项目。任何对象都足以隐式转为dynamic。

3、在以项目当作班值日(如 is 运算符或 as 运算符左边卡塔 尔(英语:State of Qatar)可能当做 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();

测量试验结果:
图片 2

 

故而你一定要实践呈现转变,这并不保险什么,仅仅因为借使不调换,编写翻译器不会令你运营。

dynamic 简化反射

早先笔者们这么使用反射:

public class DynamicSample
{
public string Name { get; set; }

public int Add(int a, int b)
{
return a   b;
}
}
DynamicSample dynamicSample = new DynamicSample(); //create instance为了简化演示,我没有使用反射
var addMethod = typeof(DynamicSample).GetMethod("Add");
int re = (int)addMethod.Invoke(dynamicSample, new object[] { 1, 2 });

这几天,我们有了简化的写法:

dynamic dynamicSample2 = new DynamicSample();
int re2 = dynamicSample2.Add(1, 2);

 dynamic的实践功能

有关dynamic的效能难题,这里暂不张开,后续特意来商讨...

新的dynamic关键字来了。它报告编译器不要强制附加准则在你的代码上。

var,dynamic,守旧明显项目标成效相比较

历史观类别的频率 >= var动态类型 > dynamic动态类型

编写翻译器对dynamic进行了优化,比未有通过缓存的反光功能高。

参照他事他说加以考察作品:


应用

1、自动反射

2、COM组件互操作

3、混合编制程序,比方IronRuby和IronPython

4、处理Html DOM对象

5、还应该有意气风发种选用,数据传输中格式转变,如:对象转json等,很有利

 

 

dynamic dyn = 10;

Console.WriteLine(dyn.GetType());

// 跟"object"一样. 

// 输出 System.Int32 因为

// 那是那个目的里累积的值的品种。

// 未有编译错误,因为 

// 编写翻译器不会在编写翻译时

// 试图识别dynamic对象的门类。

dyn = dyn 10;

 

// 相似,这些操作会在富有数值或

// 其余扶植“ ”操作符的品种上成功运算。

dyn = 10.0;

dyn = dyn 10;

dyn = "10";

dyn = dyn 10;

 

那是叁个object和dynamic间的要紧分歧----用dynamic相当于你告知编写翻译器此指标的花色只在运作时规定,编写翻译器不会估算干预。最后,你能够写更加少的代码。但自己要重申一下,相对于选用原有的object关键字,那样做不会追加其余危殆。相通,也不会减削别的危急,所以当操作任何对象急需类型检查技艺时(如反射),则使用dynamic对象会更加好。

接下去平时会晤世如下难题:“既然dynamic对象能够是不管三七三十风流倜傥对象而且编译器不会检讨它是什么样,这是不是意味你能够传递多少个dynamic对象给笔者的信赖措施/系统并使它崩溃?”

让大家假诺具备叁个简易方法。

 

public static void Print(string arg)

{

         Console.WriteLine(arg);

}

 

今天大家看看您能怎么传递dynamic对象给它。

 

dynamic dyn = 10;

// 你将于运作时在那获得叁个极度.

Print(dyn);

 

您能够瞥见,即便编写翻译器允许你传递一个dynamic对象给你的法子,但您的办法恒久不会拿到那么些目的若是它是个谬误的类型。在措施其实执行此前早就有三个充足抛出。独有当它包含贰个妥当班值日时,你技术传递dynamic对象给你的法子,在那处是string类型。

 

dynamic dyn = "10";

Print(dyn);

 

再也重申,这跟你利用object关键字比较不会有太多作为上的区别。

 

// 不会编写翻译通过.

//Print(obj);

// 编写翻译, 但这里在运行时会有个可怜。

//Print((string)obj);

// 这里的代码会寻常专门的学问,因为后天obj是个string型,

// 但你不需求改造。

obj = "10";

Print((string)obj);

 

有一些人会讲(int)obj这种写法并简单通晓,为啥要再来个dynamic呢?行吗,有个别意况下你只可以施行相当多的转移操作,那使得你的代码很难掌握。还会有个别情形下轻松的改造并无法实现指标,你供给调用反射方法,例如InvokeMember或GetProperties。贰个很好的例证就是COM互操作,那便是怎么它要改过以利用新dynamic天性(更多音讯点这里“how-to”.aspx))。

还要,用dynamic关键字和dynamic语言运转时让无数在先不容许完成或难以实现的方案变得实惠,包蕴与动态语言互操作。小编在头里的博客里着重提出过那八个情状: Introducing ExpandoObject 和Creating Wrappers with DynamicObject.

您大概想去MSDN walkthrough.aspx)看看,它显示你该怎么从C#和Visual Basic调用IronPython库,一个实在超级帅的牵线,Using Dynamic Languages to Build Scriptable Applications,小编Dino Viehland。另三个好的介绍显示一些事例并分解设计条件背后是以此性格Dynamic Binding in C# 4,作者Mads Torgersen。

敲定是我们无需操心会有人能用dynamic性子破坏你的代码。它从不越来越多(同一时间,也一贯不更加少卡塔 尔(阿拉伯语:قطر‎的危险相对于object关键字。

故而,假让你时常应用object关键字而且只好实行一批示后转载换"况且/恐怕"使用反射来调用对象的方法或性质,你大概应该注意一下dynamic关键字。在不知凡几时候它比object更有利而且编写更加少的代码。

原稿未有关系var关键字,相信广大人会在这里儿想到var。

var在C#3.0中爆发,其在MSDN中的定义:在方式范围中宣称的变量能够具备隐式类型 var。隐式类型的本地变量是强类型变量(就恍如你已经宣称该项目同样卡塔 尔(阿拉伯语:قطر‎,但由编写翻译器鲜明项目。

选用var关键字评释变量,编写翻译器会依据分配的实例类型显著此变量的花色,即类型估摸。

 

var va = 10;

Console.WriteLine(va.GetType());

// 输出 System.Int32 因为

// 这是那个目的里积攒的值的门类。

// 而va的编写翻译时类型也早就被编写翻译器分明为int型。

// 未有编写翻译错误,因为 

// va在首先句赋值时

// 便被编写翻译器明显其项目是int。

va = va 10;

// 编写翻译错误,因为

// va变量已经规定是int型,而10.0是double型,

// 且double型向int型不可隐式转变。

// va = 10.0;

 

跟object比,var归属强类型;

跟dynamic比,var并无此外运行时的动态个性,仅仅是编写翻译器在编写翻译时反向推断其体系,同直接用其编写翻译时类型表明变量功能上是风流倜傥律的。它不过是编写翻译器提供的语法糖。dynamic可不是语法糖,dynamic是急需周转时援救的。

 

VA福睿斯 是3.5新出的八个概念变量的门类
事实上也正是减弱类型的定义
VA奥迪Q3可替代任何类型
编译器会依靠上下文来判定你到底是想用什么类型的

有关什么情况下用到VA库罗德 小编想便是您一点都不大概鲜明自己将用的是如何类型
就足以选取VALAND 相仿 OBJECT
可是成效比OBJECT高点

动用var定义变量时有以下多少个特征:

  1. 必得在概念时初叶化。约等于必需是var s = “abcd”格局,而不能够是之类情势:

var s;

s = “abcd”;

  1. 生机勃勃但初叶化完结,就不可能再给变量赋与伊始化值类型差异的值了。

  2. var须要是一些变量。

4. 用到var定义变量和object不相同,它在功效上和平运动用强类型格局定义变量完全同样。

 

var代表“变量的品类是在编写翻译时间调控制的”,然则dynamic表示“变量的类别是在运维时间调控制的”。由此,dynamic与var具有完全差别的意义。 

var令你在开首化变量时少输入一些字,编写翻译器会基于右值来推论出变量的等级次序。dynamic更决定,它报告编写翻译器,根本就别理毕竟是甚类型,运维时再推测不迟。

var只可以用来局部变量的概念,你不可能把类的属性定义成 var,也不可能把艺术的回到值类型可能是参数类型定义成var。dynamic就不曾那个局限了。

dynamic类型并未有跳过类型校验,只是延迟到了运维时。若是在运营时,检测到品种不合作,照样会抛出拾叁分。

您可能在以下情状下利用dynamic:

1.COM对象

2.动态语言(如IronPython,IronRuby等)对象

3.反光对象

4.C# 4.0中动态创立的指标

本文由pc28.am发布于计算机编程,转载请注明出处:编制程序总计,动态目的

上一篇:动态编写翻译,在线运转 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • 编制程序总计,动态目的
    编制程序总计,动态目的
    dynamic是FrameWork4.0的新特色。dynamic的现身让C#具备了弱语言类型的风味。编写翻译器在编写翻译的时候不再对项目举行检查,编译期暗中同意dynamic对象扶植
  • 动态编写翻译,在线运转
    动态编写翻译,在线运转
    千帆竞发产生c#代码的在线编辑。     在帮顾客写JAVA客商端访谈.NET达成的Webservice的示范代码发掘了一个有意思的标题。为有保持安全性,使用了wse2.0sp
  • 二叉树中度为2的结点
    二叉树中度为2的结点
    int Degree2(BitNode *t){ if(t==null) return 0;if(t-lchild!=nullt-rchild!=null) return 1 Degree2(t-lchild) Degree2(t-rchild);return Degree2(t-lchild) Degree2(t-rchild); } 您可能感兴趣的 非递归先
  • 包的区别
    包的区别
    大家平常在python的模块目录中会看见" __init__.py " 那个文件,那么它终归有啥样功效吗? 类 类的概念在不胜枚举语言中出现,相当轻便驾驭。它将数据和操
  • 开发的进化史,中的发展
    开发的进化史,中的发展
    三、查询集合 本文内容 引入 概述 匿名函数     Lambda 表达式     匿名方法 参看资料 引入 本文在 VS 2008 环境下,阐述自己对 Lambda 表达式、匿名函数、