【美高梅开户网址】中dynamic的正确用法,编制程序总计

dynamic是FrameWork肆.0的新特色。dynamic的出现让C#具有了弱语言类型的性格。编写翻译器在编写翻译的时候不再对品种举办检查,编写翻译期暗中认可dynamic对象援助你想要的此外个性。比如,就算你对GetDynamicObject方法重临的靶子一窍不通,你也能够像如下那样进行代码的调用,编写翻译器不会报错:

dynamic是FrameWork四.0的新特点。
dynamic的面世让C#全数了弱语言类型的天性。编写翻译器在编写翻译的时候不再对品种实行自作者批评,编写翻译期默许dynamic对象支持你想要的别的性子。比如,
固然你对GetDynamicObject方法重回的目的一无所知,你也足以像如下那样进行代码的调用,编写翻译器不会报错:

C#编制程序计算(拾肆)dynamic

让大家十分的快看看object关键字先。笔者不会对它讲太多,因为它在C#1.0就已经有了。这一个重中之重字未有更多东西除了作为System.Object的快速方式,System.Object是C#类层次的根类型。(然则,正如埃里克Lippert在她博客中提出,并非任何类型都连任源于object[中][英])那是2个有力的体制,那样你大概能够分配任何实例值到此类型。

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

 

介绍

Visual
C# 2010 引进了1个新品类 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变量使用“智能感知”,会唤醒“此操作就要运营时分析”。

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

var与dynamic对比

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

若果被编写翻译,编写翻译期会自动相称var
变量的莫过于类型,并用实际类型来替换该变量的注脚,那看起来就仿佛大家在编码的时候是用实际类型进行表明的。而dynamic被编写翻译后,实际是2个object类型,只可是编写翻译器会对dynamic类型举办超过常规规处理,让它在编写翻译时期不开始展览任何的项目检查,而是将项目检查放到了运维期。

二、智能感知。

以var声明的变量,补助“智能感知”,因为visual
studion能推断出var类型的实际上类型,而以dynamic评释的变量却不援救“智能感知”,因为编写翻译器对其运营期的档次一窍不通。对dynamic变量使用“智能感知”,会提醒“此操作就要运营时解析”。

 

object obj = 10;

Console.WriteLine(obj.GetType());

// 输出 System.Int32 因为

// 那是以此指标里积存的值的项目。

// 3个编译错误, 因为 

// 在编写翻译时obj的种类是System.Object。

// obj = obj + 10;

// 你必要显式调换obj到希望的门类。

obj = (int)obj + 10;

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

// 你或者调换来1个不当的花色 

// 而编写翻译器并不会发现。 

// 那里您会在运转时获得3个不行, 

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

说起科学用法,那么首先应该建议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);
        }
    }
}

看望产生什么职业吗,通过测试发现:

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

运维时抛出非常,十分消息:

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

运维结果:

美高梅开户网址 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值,假诺没有改动,编写翻译器照旧不会让您试行别的数学操作。它看起来好像是援救您鲜明是或不是你真有1个int类型,但它不是。你能够转变成二个全然两样的门类但编写翻译器却检查不出。结果正是,你收获贰个周转时那些。

艺术中蕴涵dynamic类型参数的重载难点

假如调用二个方法是传递了dynamic类型的目的,只怕被调用的靶子是dynamic类型的,那么重载的剖断是产生在运作时而不是编写翻译时。
动态语言运转时(dynamic language runtime DL大切诺基)动态语言运维时是.NET
Framework 四 Beta
1中的1组新的API,它提供了对c#中dynamic类型的支撑,也落到实处了像IronPython和IronRuby之类的动态程序设计语言。

一生人会拿var这几个第二字来和dynamic做相比。实际
上,var和dynamic完全是多个概念,根本不应有放在一齐做比较。var实际上是编写翻译期抛给我们的“语法糖”,一旦被编写翻译,编写翻译期会自动匹配var
变量的实际类型,并用实际类型来替换该变量的声明,那看起来就恍如大家在编码的时候是用实际类型举行说明的。而dynamic被编写翻译后,实际是3个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();

【美高梅开户网址】中dynamic的正确用法,编制程序总计。测试结果:
美高梅开户网址 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变量是1个object变量这点,可以经过IL代码拿到验证,那里不再贴出IL代码。当然,编写翻译器也对dynamic评释举办了拍卖,以分别直接object变量。

应用

1、自动反射

2、COM组件互操作

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

4、处理Html DOM对象

伍、还有一种选取,数据传输中格式转变,如:对象转json等,很便利

 

 

dynamic是做为简化互操作性而被MSDN中山高校肆渲染,
小编感觉到正是依照那点,才被壹些开荒人士误解:因为好些个开采人士不会接触COM+、OFFICE三遍支付之类的编码,所以急供给1个dynamic的应用
理由。那么,在平凡支出中,小编认为dynamic很有价值的有个别是:

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类型实例,见上面包车型地铁事例:

接下去1般会合世如下难点:“既然dynamic对象能够是随意对象并且编写翻译器不会检讨它是如何,那是还是不是意味着你能够传递二个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;

// 你将于运作时在那里收获3个分外.

Print(dyn);

 

int i = d1;

您能够望见,纵然编写翻译器允许你传递3个dynamic对象给你的章程,但您的章程长久不会赢得这一个目的如果它是个错误的品类。在格局其实执行在此之前已经有一个卓殊抛出。唯有当它含有二个妥善班值日时,你能力传递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。一个很好的例证就是COM互操作,那正是干什么它要修改以使用新dynamic特性(更多音讯点这里“how-to”.aspx))。

一经调用3个办法是传递了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中学的1组新的API,它提供了对c#中dynamic类型的协助,也促成了像IronPython和IronRuby之类的动态程序设计语言。

敲定是我们不须要顾忌会有人能用dynamic天性破坏你的代码。它从不越来越多(同时,也远非更加少)的险恶相对于object关键字。

dynamic能够简化反射

故而,倘使你平日应用object关键字并且不得不实施一批示后转载换”并且/只怕”使用反射来调用对象的措施或性质,你或许应该专注一下dynamic关键字。在众多时候它比object更有益而且编写更加少的代码。

原先大家这么使用反射:

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

 

var在C#三.0中发出,其在MSDN中的定义:在格局范围中证明的变量能够具备隐式类型
var。隐式类型的地面变量是强类型变量(就象是你已经宣称该类型相同),但由编写翻译器鲜明项目。

美高梅开户网址 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;
    }
    }
    DynamicSample dynamic萨姆ple = new DynamicSample(); //create
    instance为了简化演示,笔者尚未运用反射
    var addMethod = typeof(DynamicSample).GetMethod(“Add”);
    int re = (int)addMethod.Invoke(dynamicSample, new object[] { 1, 2
    });

跟dynamic比,var并无其余运营时的动态性情,仅仅是编写翻译器在编写翻译时反向猜想其项目,同直接用其编写翻译时类型表明变量功用上是一律的。它唯有是编译器提供的语法糖。dynamic可不是语法糖,dynamic是内需周转时协助的。

美高梅开户网址 4

 

近日,大家有了简化的写法:

VAXC90 是③.五新出的一个概念变量的花色
事实上约等于减弱类型的定义
VAEscort可取代任何类型
编写翻译器会基于上下文来判别你到底是想用什么项目标

dynamic
dynamicSample2 = new DynamicSample();

关于哪些动静下用到VAEnclave 小编想正是您无法鲜明本人将用的是怎样类型
就足以行使VA锐界 类似 OBJECT
而是效用比OBJECT高点

int re2

dynamicSample2.Add(1, 2);

大家只怕会对这么的简化不以为然,毕竟看起来代码并未收缩多少,不过,要是设想到功效兼杰出两特性状,那么dynamic的优势就显现出来了。编写翻译器对dynamic进行了优化,比未有通过缓存的反光功用快了数不胜数。假使非要比较,可以将下面两者的代码(调用Add方法某个)运营一千000就足以得出结论。

利用var定义变量时有以下八个特征:

  1. 必须在概念时初步化。也正是必须是var s =
    “abcd”情势,而不可能是之类情势:

var s;

s = “abcd”;

  1. 一但初叶化实现,就不能够再给变量赋与开始化值类型不一致的值了。

  2. var须求是一对变量。

四.
行使var定义变量和object不一致,它在作用上和应用强类型方式定义变量完全一样。

 

var代表“变量的花色是在编写翻译时间调整制的”,不过dynamic表示“变量的连串是在运转时间调整制的”。因而,dynamic与var具备完全分歧的意义。 

var让你在开首化变量时少输入壹些字,编写翻译器会依照右值来猜想出变量的项目。dynamic越来越厉害,它告诉编译器,根本就别理究竟是甚类型,运营时再猜想不迟。

var只可以用于局地变量的概念,你无法把类的习性定义成
var,也不能够把措施的回到值类型恐怕是参数类型定义成var。dynamic就从未这么些局限了。

dynamic类型并从未跳过类型校验,只是延迟到了运维时。如若在运营时,检查评定到花色不相称,照样会抛出万分。

你恐怕在偏下意况下使用dynamic:

1.COM对象

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

3.反光对象

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图