dynamic是FrameWork四.0的新天性。dynamic的产出让C#有着了弱语言类型的特点。编写翻译器在编写翻译的时候不再对项目举办检讨,编写翻译期私下认可dynamic对象援助您想要的其余性情。比如,固然你对GetDynamicObject方法再次回到的对象一窍不通,你也能够像如下那样实行代码的调用,编写翻译器不会报错:

dynamic是FrameWork四.0的新特色。
dynamic的面世让C#有着了弱语言类型的特征。编写翻译器在编写翻译的时候不再对品种举办检查,编写翻译期私下认可dynamic对象补助你想要的别的性格。比如,
纵然你对GetDynamicObject方法重返的对象一窍不通,你也得以像如下那样进行代码的调用,编写翻译器不会报错:

C#编制程序总括(十四)dynamic

让大家快捷看看object关键字先。作者不会对它讲太多,因为它在C#一.0就早已有了。那几个关键字未有越多东西除了作为System.Object的快速方式,System.Object是C#类层次的根类型。(不过,正如Eric利普珀特t在他博客中建议,毫不全数类型都持续源于object[中][英])那是两个精锐的建制,那样您大致能够分配任何实例值到此类型。

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

 

介绍

Visual
C# 20十 引进了1个新类型 dynamic。 该类型是1种静态类型,但项目为 dynamic 的目的会跳过静态类型检查。 大繁多景色下,该指标就好像具有类型 object 一样。 在编写翻译时,将假定类型化为 dynamic 的要素支持任何操作。 因而,您不用思索对象是从
COM API、从动态语言(例如 IronPython)、从 HTML 文书档案对象模型
(DOM)、从反射照旧从程序中的其他地点获取自身的值。 可是,借使代码无效,则在运行时会捕获到错误。

 

那是个小例子用来演示使用object关键字的便宜和难点。

dynamic与var关键字本质差别

var只可以用作一些变量,无法用来字段,参数;申明的同时必须早先化;伊始化时类型就曾经明确了,并且不能够再被赋值无法进行隐式类型调换的品类的数量。

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

dynamic可用来项目标字段,方法参数,方法重返值,可用以泛型的档次参数等;能够赋值给或被赋值任何类型并且不要求显式的威迫类型转变,因为这一个是运作时施行的,那要得益于dynamic类型的动态性子。

dynamic被编写翻译后,实际是二个object类型,只可是编写翻译器会对dynamic类型举办尤其处理,让它在编译时期不进行任何的档次检查,而是将品种检查放到了运转期。

从visual
studio的编辑器窗口就能看出来。以var表明的变量,帮衬“智能感知”,因为visual
studion能推断出var类型的骨子里类型,而以dynamic注脚的变量却不支持“智能感知”,因为编写翻译器对其运转期的类别一窍不通。对dynamic变量使用“智能感知”,会提示“此操作将要运维时分析”。

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

var与dynamic对比

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

设若被编写翻译,编写翻译期会自动相称var
变量的莫过于类型,并用实际类型来替换该变量的声明,那看起来就就如大家在编码的时候是用实际类型举办表明的。而dynamic被编写翻译后,实际是二个object类型,只然而编写翻译器会对dynamic类型举办超过常规规处理,让它在编写翻译时期不开始展览任何的档次检查,而是将品种检查放到了运营期。

二、智能感知。

以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;

// 要是您将其改换来一个错误的数值类型, 

// 你也会博得二个周转时1贰分 

// 即便有隐式转变的语法在此地。

// 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;

谈起正确用法,那么首先应当提议一个谬误用法:

简言之案例

编纂3个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);
        }
    }
}

看看产生什么样业务啊,通过测试发现:

编译通过,未有别的卓殊。

运行时抛出11分,非常新闻:

未处理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();
        }
    }

运作结果:

金沙注册送58 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    

【金沙注册送58】中dynamic的正确用法,编制程序计算。 

你能够看到,固然obj存款和储蓄叁个int值,假设未有改动,编写翻译器依旧不会让你施行别的数学操作。它看起来好像是支援您分明是不是你真有1个int类型,但它不是。你能够转移到八个一心两样的档次但编写翻译器却检查不出。结果便是,你赚取七个周转时尤其。

艺术中含有dynamic类型参数的重载难点

就算调用三个主意是传递了dynamic类型的靶子,可能被调用的对象是dynamic类型的,那么重载的剖断是发生在运维时而不是编写翻译时。
动态语言运营时(dynamic language runtime DL途观)动态语言运营时是.NET
Framework 四 Beta
第11中学的一组新的API,它提供了对c#中dynamic类型的协助,也完毕了像IronPython和IronRuby之类的动态程序设计语言。

素有人会拿var那个根本字来和dynamic做比较。实际
上,var和dynamic完全是三个概念,根本不应该献身一块儿做相比。var实际上是编写翻译期抛给我们的“语法糖”,壹旦被编写翻译,编写翻译期会自动相配var
变量的实在类型,并用实际类型来替换该变量的发明,那看起来就如大家在编码的时候是用实际类型进行表达的。而dynamic被编写翻译后,实际是二个object类型,只可是编写翻译器会对dynamic类型实行卓殊规处理,让它在编写翻译时期不举行其余的连串检查,而是将品种检查放到了运转期。

dynamic应用范围

一、在宣称中,作为品质、字段、索引器、参数、重返值或项目约束的类别,都能够采纳dynamic。

二、在显式类型转换中,作为调换的指标项目。任何对象都得以隐式转为dynamic。

叁、在以项目充当班值日(如 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();

测试结果:
金沙注册送58 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);

那从visual
studio的编辑器窗口就能看出来。以var表明的变量,扶助“智能感知”,因为visual
studion能测度出var类型的其实类型,而以dynamic注脚的变量却不支持“智能感知”,因为编写翻译器对其运转期的档次一窍不通。对
dynamic变量使用“智能感知”,会提醒“此操作就要运行时分析”。

 dynamic的实践作用

关于dynamic的效用难点,那里暂不张开,后续专门来钻探…

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

var,dynamic,古板鲜明项指标频率相比较

历史观项目标成效 >= var动态类型 > dynamic动态类型

编写翻译器对dynamic进行了优化,比尚未经过缓存的反光成效高。

参考小说:

有关dynamic变量是二个object变量那一点,能够经过IL代码得到验证,那里不再贴出IL代码。当然,编写翻译器也对dynamic注解举办了拍卖,以界别直接object变量。

应用

一、自动反射

二、COM组件互操作

三、混合编制程序,例如IronRuby和IronPython

4、处理Html DOM对象

5、还有1种接纳,数据传输中格式转变,如:对象转json等,很有利

 

 

dynamic是做为简化互操作性而被MSDN中山高校四渲染,
笔者认为就是依照这点,才被部分开垦职员误解:因为众多开辟职员不会接触COM+、OFFICE贰遍支付之类的编码,所以急须求二个dynamic的采取理由。那么,在平常开支中,我以为dynamic很有价值的少数是:

金沙注册送58,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类型的实例和别的类别的实例间的调换是很粗大略的,开荒职员能够很有利地在dyanmic和非dynamic行为间切换。任何实例都能隐式调换为dynamic类型实例,见上面的例证:

接下去一般会现出如下难点:“既然dynamic对象足以是轻易对象并且编写翻译器不会检查它是什么,那是或不是意味着你能够传递2个dynamic对象给自个儿的重视措施/系统并使它崩溃?”

dynamic d1 = 7;

让我们只要拥有三个简约方法。

dynamic d2 = “a string”;

 

dynamic d3 = System.DateTime.Today;

public static void Print(string arg)

{

         Console.WriteLine(arg);

}

 

dynamic d4 = System.Diagnostics.Process.GetProcesses();

于今我们看看你能怎么传递dynamic对象给它。

Conversely, an implicit conversion can be dynamically applied to any
expression of type dynamic.

 

反之同样,类型为dynamic的其它说明式也可以隐式调换为其余连串。

dynamic dyn = 10;

// 你将于运作时在那边收获三个格外.

Print(dyn);

 

int i = d1;

你能够望见,即使编写翻译器允许你传递一个dynamic对象给您的秘技,但你的章程恒久不会赢得这几个目的如若它是个谬误的类别。在点子其实实践此前早已有二个1贰分抛出。只有当它含有叁个伏贴班值日时,你手艺传递dynamic对象给你的格局,在此地是string类型。

string str = d2;

 

dynamic dyn = “10”;

Print(dyn);

 

DateTime dt = d3;

重新重申,那跟你使用object关键字相比较不会有太多表现上的分别。

System.Diagnostics.Process[] procs = d4;

 

// 不会编译通过.

//Print(obj);

// 编写翻译, 但那里在运作时会有个十二分。

//Print((string)obj);

// 那里的代码会平常干活,因为后天obj是个string型,

// 但您不供给改变。

obj = “10”;

Print((string)obj);

 

艺术中含有dynamic类型参数的重载难题

有人说(int)obj那种写法并轻松精通,为啥要再来个dynamic呢?好呢,有个别境况下你只好试行较多的转移操作,那使得你的代码很难理解。还有些景况下简单的更动并无法达成目标,你须要调用反射方法,比如InvokeMember或GetProperties。1个很好的例证正是COM互操作,那就是为啥它要修改以使用新dynamic特性(更加多消息点那里“how-to”.aspx))。

如若调用一个格局是传递了dynamic类型的对象,恐怕被调用的对象是dynamic类型的,那么重载的决断是爆发在运作时而不是编写翻译时。

与此同时,用dynamic关键字和dynamic语言运转时让众多原先不恐怕完毕或难以完毕的方案变得实惠,包蕴与动态语言互操作。我在前边的博客里重申过那多个情形: Introducing
ExpandoObject 和Creating
Wrappers with
DynamicObject.

动态语言运转时(dynamic language runtime DL帕杰罗)

你也许想去MSDN
walkthrough.aspx)看看,它彰显你该怎么从C#和Visual
Basic调用IronPython库,四个确实很酷的牵线,Using Dynamic Languages to
Build Scriptable
Applications,小编Dino
Viehland。另三个好的介绍体现1些例证并表明设计条件背后是以此特点Dynamic
Binding in C#
4,作者Mads
Torgersen。

动态语言运维时是.NET Framework 肆 Beta
第11中学的一组新的API,它提供了对c#中dynamic类型的资助,也落成了像IronPython和IronRuby之类的动态程序设计语言。

结论是大家不要求操心会有人能用dynamic脾气破坏你的代码。它从未越多(同时,也不曾越来越少)的安危相对于object关键字。

dynamic能够简化反射

故此,假若你平常利用object关键字并且只可以执行一批示后转载换”并且/大概”使用反射来调用对象的章程或性质,你只怕应该专注一下dynamic关键字。在不少时候它比object更有利于而且编写越来越少的代码。

先前我们那样使用反射:

原来的书文未有提到var关键字,相信广大人会在那时想到var。

 

var在C#三.0中发生,其在MSDN中的定义:在点子范围中声称的变量能够具备隐式类型
var。隐式类型的本地变量是强类型变量(就类似你已经宣示该类型一样),但由编写翻译器明显项目。

金沙注册送58 3

应用var关键字申明变量,编写翻译器会基于分配的实例类型明确此变量的品类,即类型估量。

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

 

var va = 10;

Console.WriteLine(va.GetType());

// 输出 System.Int32 因为

// 那是以此指标里储存的值的品种。

// 而va的编写翻译时类型也壹度被编写翻译器鲜明为int型。

// 未有编译错误,因为 

// va在率先句赋值时

// 便被编写翻译器鲜明其品种是int。

va = va + 10;

// 编写翻译错误,因为

// va变量已经明确是int型,而拾.0是double型,

// 且double型向int型不可隐式调换。

// va = 10.0;

 

public int Add(int a, int b)
{
return a

跟object比,var属于强类型;

  • b;
    }
    }
    Dynamic萨姆ple dynamicSample = new DynamicSample(); //create
    instance为了简化演示,笔者从未选取反射
    var addMethod = typeof(DynamicSample).GetMethod(“Add”);
    int re = (int)addMethod.Invoke(dynamicSample, new object[] { 1, 2
    });

跟dynamic比,var并无其余运维时的动态本性,仅仅是编写翻译器在编译时反向测度其体系,同直接用其编写翻译时类型注解变量功能上是如出一辙的。它仅仅是编写翻译器提供的语法糖。dynamic可不是语法糖,dynamic是索要周转时辅助的。

金沙注册送58 4

 

当今,大家有了简化的写法:

VAPRADO 是3.5新出的1个概念变量的项目
实际也正是弱化类型的定义
VA君越可代替任何项目
编写翻译器会基于上下文来判定你究竟是想用什么类型的

dynamic
dynamicSample2 = new DynamicSample();

关于怎么样情状下用到VA奔驰M级 作者想正是你相当的小概分明自身将用的是什么样品种
就足以接纳VACR-V 类似 OBJECT
只是作用比OBJECT高点

int re2

dynamicSample2.Add(1, 2);

小编们可能会对如此的简化不感到然,毕竟看起来代码并未收缩多少,不过,假诺设想到成效兼赏心悦目七个特点,那么dynamic的优势就显现出来了。编写翻译器对dynamic实行了优化,比未有通过缓存的反射作用快了许多。要是非要比较,能够将上边两者的代码(调用Add方法某个)运营一千000就足以得出结论。

使用var定义变量时有以下几天性状:

  1. 务必在概念时开端化。相当于必须是var s =
    “abcd”形式,而不能是之类格局:

var s;

s = “abcd”;

  1. 一但起头化达成,就不能够再给变量赋与开头化值类型不一致的值了。

  2. var供给是1些变量。

四.
施用var定义变量和object分歧,它在效用上和动用强类型方式定义变量完全等同。

 

var表示“变量的体系是在编写翻译时调节的”,然而dynamic表示“变量的品类是在运作时间调节制的”。由此,dynamic与var具备完全差异的意义。 

var让你在开端化变量时少输入壹些字,编写翻译器会基于右值来揆度出变量的档次。dynamic更决心,它报告编译器,根本就别理终究是什么类型,运营时再臆想不迟。

var只可以用于局地变量的定义,你无法把类的习性定义成
var,也不能够把措施的回来值类型也许是参数类型定义成var。dynamic就向来不这一个局限了。

dynamic类型并未跳过类型校验,只是延迟到了运转时。假若在运转时,检查实验到品种不相称,照样会抛出分外。

您只怕在以下景况下使用dynamic:

1.COM对象

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

三.反光对象

4.C# 4.0中动态创设的靶子

相关文章

网站地图xml地图