麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > C# > 正文

C# dynamic關(guān)鍵字的使用方法

2020-01-24 03:25:14
字體:
供稿:網(wǎng)友

C#是一種類型安全的編程語言(所有表達(dá)式都能解析成某個類型的實(shí)例,在編譯器生成的代碼中,只會執(zhí)行對這個類型有效的操作),和非類型安全的語言相比,類型安全的優(yōu)勢就體現(xiàn)出來了:
1.許多錯誤能在編譯時檢測到,取保代碼在執(zhí)行它之前是正確的。
2.編譯時語言通常能生成更小,更快的代碼。(在編譯時進(jìn)行更多的假設(shè),并在IL和元數(shù)據(jù)中落實(shí)那些假設(shè))

為了方便開發(fā)人員使用反射或者與基本組件通信,dynamic誕生了!
一下代碼展示了如何利用反射在一個String目標(biāo)("根據(jù)我找類型")上調(diào)用一個方法(“Contains”),向它傳遞一個實(shí)參(“我只是一個string參數(shù)”),并將結(jié)果存儲到局部變量result中。

復(fù)制代碼 代碼如下:

static void Main()
        {
            object target = "根據(jù)我找類型";
            object arg = "我只是個string參數(shù)";
            Type[] argtype = new Type[] { arg.GetType()};
            System.Reflection.MethodInfo method = target.GetType().GetMethod("Contains", argtype);

            object[] argm = new object[] { arg};
            Boolean result=Convert.ToBoolean(method.Invoke(target,argm));
}


現(xiàn)在,有了dynamic!
復(fù)制代碼 代碼如下:

static void Main()
        {
            dynamic target = "根據(jù)我找類型";
            dynamic arg = "參數(shù)";
            Boolean result = target.Contains(arg);
}

是不是發(fā)現(xiàn)有了顯著的簡化。
復(fù)制代碼 代碼如下:

static void Main()
        {
            Application excel = new Application();
            excel.Visible = true;
            excel.Workbooks.Add(Type.Missing);
            ((Range)excel.Cells[1, 1]).Value = //www.companysz.com/smailxiaobai/archive/2011/11/25/"放入單元格的字符";//如果沒有dynamic類型,excel.Cells[1,1]的返回值是objec類型,必須先把它轉(zhuǎn)換為Rang類型才能訪問Value屬性。
            excel.Cells[1, 1].Value = //www.companysz.com/smailxiaobai/archive/2011/11/25/"放入單元格的字符";//為COM對象生成一個可由“運(yùn)行時”調(diào)用的包裝程序集時,COM方法中使用的任何variant實(shí)際都會被轉(zhuǎn)換為dynamic,這稱為動態(tài)化(dynamicfication)。
            //所以這里excel.Cells[1,1]是dynamic類型,可以不必顯示把它轉(zhuǎn)換成Range類型也能訪問它的Value。動態(tài)化顯著簡化了與COM對象的互操作。
        }

看到了dynamic的神奇,那再讓我們刨根問底吧。
我們可以用dynamic表達(dá)式或變量調(diào)用一個成員,比如字段,屬性/索引器,方法,委托,以及一元/二元/轉(zhuǎn)換操作符,當(dāng)我們的代碼使用dynamic表達(dá)式或變量調(diào)用一個成員時,編譯器會生成特殊的IL代碼來描述所需的操作。
這種特殊的代碼稱為payload(有效載荷)(這些payload代碼使用了一個稱為運(yùn)行時綁定器(runtime binder)的類),在運(yùn)行時,payload代碼根據(jù)當(dāng)前由dynamic表達(dá)式/變量引用的對象的實(shí)際類型來決定具體的操作。
看這個例子:
復(fù)制代碼 代碼如下:

        static void Main()
        {
            for (int i = 0; i < 2; i++)
            {
                dynamic arg = (i == 0) ? (dynamic)10 : "A";
                dynamic result = plus(arg);//第一次循環(huán)i==0 ,arg=10;所以調(diào)用plus時,返回的是int類型。第二次是string類型。
                M(result);//payload代碼判斷出傳給M的值的實(shí)際類型,然后調(diào)用相應(yīng)的重載方法。
            }
          Console.ReadKey();
        }
        static dynamic plus(dynamic arg) { return arg+arg;}
        static  void M(int n) { Console.WriteLine("M(int):{0}", n); }
       static void M(string s) { Console.WriteLine("M(string):{0}", s); }
    }

在字段類型,方法參數(shù)類型或方法類型被指定為dynamic的前提下,編譯器會將這個類型轉(zhuǎn)換為System.Object,并在元數(shù)據(jù)中向字段,參數(shù)或者返回類型應(yīng)用System.Runtime.CompilerSevices.DynamicAttribute的一個實(shí)例。如果是一個局部變量被指定為dynamic,變量類型也會成為Object,但不會向局部變量應(yīng)用DynamicAttribute,應(yīng)為它的使用限制在方法之內(nèi)。
由于dynamic就是object 所以不僅僅將dynamic變成object,或者object變成dynamic就獲取兩個不同的方法簽名。例子:
復(fù)制代碼 代碼如下:

  object dd(dynamic i) { return i; }
 dynamic dd( object i) {return i; }

這就通不過編譯。
dynam的類型轉(zhuǎn)換:
復(fù)制代碼 代碼如下:

 static void Main()
        {
            object o = 123;//(裝箱)
            Int32 n = o;//錯誤!不允許從object到int32的隱式轉(zhuǎn)換。
            Int32 n1 = (Int32)o;//從object顯示轉(zhuǎn)換到int32。(拆箱)

            dynamic od = 123;//(裝箱)
            dynamic os = "dsfsdf";
            Int32 ns = os;//運(yùn)行時報(bào)錯。
            Int32 nd = od;//從dynamic隱式轉(zhuǎn)換為int32(拆箱)
            //在本例中可看出,dynamic轉(zhuǎn)為其他類型時,允許省略顯示轉(zhuǎn)型。
            //但是CLR會在運(yùn)行時驗(yàn)證轉(zhuǎn)型,確保類型安全。如果對象類型不兼容要轉(zhuǎn)換成的類型,clr就會拋出一個InvalidCastException異常。
        }


dynamic和var的區(qū)別:
1.var聲明一個局部變量只是一種簡化語法,它要求編譯器根據(jù)一個表達(dá)式推斷具體的數(shù)據(jù)類型。
2.var只能用于聲明方法內(nèi)部的局部變量,而dynamic可用于局部變量,字段,參數(shù)。
3.表達(dá)式不能轉(zhuǎn)型為var,但能轉(zhuǎn)型為dynamic。
4.必須顯式初始化用var聲明的變量,但無需初始化用dynam聲明的變量。
使用dynamic應(yīng)注意:
在運(yùn)行時,Microsoft.Csharp.dll必須加載到AppDomain中,這回?fù)p害程序性能,并增大內(nèi)錯耗用,Microsoft.Csharp.dll還會加載System.dll和System.Core.dll,如果使用dynamic與COM組件互操作,還會加載System.Dynamic.dll,payload代碼執(zhí)行時會在運(yùn)行時生成動態(tài)代碼。這些代碼會進(jìn)入一個駐留在內(nèi)存的程序集,稱為“匿名寄宿的DynamicMethods程序集”(Anonymously Hosted DynamicMethods Assembly).
當(dāng)一個特性的調(diào)用使用具有相同運(yùn)行時類型的dynamic實(shí)參發(fā)出了大量調(diào)用時,這個代碼可以增強(qiáng)調(diào)度的性能。
雖然dynamic能簡化語法,但是動態(tài)求值功能產(chǎn)生的額外開銷也是不容忽視的,畢竟加載所有這些程序集以及額外的內(nèi)存消耗,會對性能產(chǎn)生額外的影響。如果程序中只是一兩個地方需要動態(tài)行為,或許傳統(tǒng)的做法會更加高效。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91性高湖久久久久久久久网站 | 亚洲精品久久久久久下一站 | 电影一级毛片 | 欧美女同hd | 中文字幕在线观看1 | 黄色视频a级毛片 | 国产黄色一级大片 | 国产精品免费一区二区三区都可以 | 免费看成人av | 欧美性成人| 粉嫩蜜桃麻豆免费大片 | 日日草夜夜 | avav在线播放 | 九九夜夜| 国产亚洲精品yxsp | 黄色美女免费 | 一区二区三区欧美日韩 | 国产69精品久久久久99尤 | 精品国产一区三区| 蜜桃传媒视频麻豆第一区免费观看 | 九色com | 污片视频在线观看 | 久草在线视频在线 | 久久人人av | 视频一区二区精品 | 又黄又爽免费无遮挡在线观看 | 性插视频| 久久久久国产精品久久久久 | 精品一区二区久久久久 | 中文字幕精品在线视频 | 毛片免费视频播放 | 亚洲一级片在线观看 | 久久艹艹艹 | 久久精品国产99久久6动漫亮点 | 97精品国产高清在线看入口 | 久久久久国产成人精品亚洲午夜 | 一级黄色毛片播放 | 免费一级毛片观看 | 久久久一区二区三区四区 | 日韩精品中文字幕一区 | 日本在线一区二区 |