激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - c#使用dynamic類型優化反射的方法

c#使用dynamic類型優化反射的方法

2022-03-06 13:29Fode C#

dynamic是FrameWork4.0的新特性,下面這篇文章主要給大家介紹了關于c#使用dynamic類型優化反射的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學

什么是dynamic類型?

微軟給出的官方文檔中這樣解釋:在通過 dynamic 類型實現的操作中,該類型的作用是繞過編譯時類型檢查。 改為在運行時解析這些操作。 dynamic 類型簡化了對 COM API(例如 Office Automation API)、動態 API(例如 IronPython 庫)和 HTML 文檔對象模型 (DOM) 的訪問。在大多數情況下,dynamic 類型與 object 類型的行為類似。 但是,如果操作包含 dynamic 類型的表達式,那么不會通過編譯器對該操作進行解析或類型檢查。 編譯器將有關該操作信息打包在一起,之后這些信息會用于在運行時評估操作。 在此過程中,dynamic類型的變量會編譯為 object 類型的變量。 因此,dynamic 類型只在編譯時存在,在運行時則不存在。

dynamic的出現讓C#具有了弱語言類型的特性。編譯器在編譯的時候不再對類型進行檢查,編譯期默認dynamic對象支持你想要的任何特性。

下例中生成的類型是一致的:

?
1
2
3
4
5
dynamic dyn = "Fode";        Object obj = "Fode";
// Rest the mouse pointer over dyn and obj to see their
 // types at compile time.
 System.Console.WriteLine(dyn.GetType());
 System.Console.WriteLine(obj.GetType());

其輸出結果都是String類型,可知CLR可以正確的識別出dynamic是哪種類型,在反編譯看看其生成的IL代碼:

?
1
2
3
4
5
6
7
8
IL_0000: nop
 IL_0001: ldstr "Fode"
 IL_0006: stloc.0
 IL_0007: ldstr "Fode"
 IL_000c: stloc.1
 IL_000d: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
 IL_0012: pop
 IL_0013: ret

JIT編譯器將dynamic識別為String類型,并將其推算到運算棧中(IL代碼中 ldstr(將新對象引用推送到存儲在元數據中的字符串文字)、(stloc.*)從評估堆棧的頂部彈出當前值,并將其存儲在索引*處的本地變量列表中),不同IL代碼也不所謂,前文只是介紹dynamic這個類型關鍵字,只需要你知道他的類型是繞過編譯器就可以,如以下操作,Object類型就會報編譯的錯誤。但是,對于 dyn + 3,不會報告任何錯誤。 在編譯時不會檢查包含 dyn 的表達式,原因是 dyn 的類型為 dynamic。

?
1
2
3
4
dynamic dyn = "Fode";
Object obj = "Fode";
dyn = dyn + 3;
obj = obj + 3; //這句代碼編譯器會報錯

dynamic是Framework 4.0的新特性。dynamic的出現讓C#具有了若語言的特性。編譯器在編譯時候不再對該類型進行檢查,編譯器默認dynamic對象支持開發者想要的任何特征。比如,即使你對 GetStudent()方法返回的對象一無所知,也可以像以下執行代碼的調用,編譯器不會報錯:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static void Main(string[] args)
 {
  dynamic dyn = GetStudent();
 
  //正確的操作
  Console.WriteLine(dyn.Age);
  Console.WriteLine(dyn.Name);
  dyn.PrintName();
 
  //錯誤的操作
  //Console.WriteLine(dyn.Birthday); //該對象沒有包含該屬性
  //dyn.PrintAge(); //這行代碼會報錯誤,訪問級別不夠
  Console.ReadKey();
 }
 static Student GetStudent()
 {
  Student student = new Student();
  student.Age = 21;
  student.Name = "Fode";
  return student;
 }
 
 class Student
 {
  public String Name { get; set; }
  public Int32 Age { get; set; }
 
  public void PrintName()
  {
  Console.WriteLine(this.Name);
  }
 
  private void PrintAge()
  {
  Console.WriteLine(this.Age);
  }
 }

如果運行時dyn對象不包含指定的特性(屬性、字段、方法等),運行時會拋出一個運行時的錯誤 RuntimeBinderException。

注意:有人可能會將var關鍵字與dynamic進行比較。實際上,var和dynamic完全是兩回事,兩個不同的概念。var實際上是編譯期間拋給我門的“語法糖”,一旦被編譯,編譯器會自動匹配var變量的實際類型,并用實際類型來替換給變量的聲明,這看上去就好像我們在編碼的時候用實際類型進行聲明一樣,優點也顯而易見,當【賦值方】類型發生變化時,【實現方】無需改變其類型,因為var會自動去適配。而dynamic被編譯后,實際上是一個Object類型,只不過編譯器會對dynamic類型進行特殊處理,讓它在編譯期間不進行任何的類型檢查,而是將類型檢查放到了運行期。這從VS這個IDE就能看出,在編輯窗口中,var支持【智能感知】,因為vs能推斷出var類型的實際類型;而dynamic聲明的變量卻不支持【智能感知】,因為對其運行期的類型一無所知。對dynamic變量使用【智能感知】會提示"此操作將在運行時解析"。

BB了這么久,重點來了,利用好了動態類型dynamic的這個特性,可以簡化C#中的反射語法,更高深的優化將在以后的博客推出。在dynamic出現之前,我們先用基礎反射獲取一個類中的方法,并執行它:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void Main()
 {
  DynamicObj obj = new DynamicObj();
  var fun = obj.GetType().GetMethod(nameof(obj.CallFun));
  Int32 result = (Int32)fun.Invoke(obj, new Object[] { "Fode" });
  Console.WriteLine(result);
  Console.ReadKey();
 }
 
 public class DynamicObj
 {
  public Int32 CallFun(String str)
  {
  return str.Length;
  }
 }

其結果沒有什么好講的,就是一個用反射調用 CallFun() 方法的例子,而用dynamic之后,代碼看上去更簡潔了,并且在可控制的范圍內減少了一次拆箱的操作,代碼如下:

?
1
2
3
dynamic dyn = new DynamicObj();
Int32 result = dyn.CallFun("Fode");
Console.WriteLine(result);

可能我們會對這樣的簡化不以為然,畢竟代碼看起來并沒有減少多少,但是,如果考慮到效率兼優美兩個特性,那么dynamic的優勢就顯現出來了。對上面的代碼個執行10000000次,在進行分析,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
CodeTimer.Time("使用dynamic", 10000000, () => { //執行里面的代碼10000000次
  dynamic dyn = new DynamicObj();
  Int32 result = dyn.CallFun("Fode");
  });
 
  CodeTimer.Time("使用基礎反射", 10000000, () => { //執行里面的代碼10000000次
  DynamicObj obj = new DynamicObj();
  var fun = obj.GetType().GetMethod(nameof(obj.CallFun));
  Int32 result = (Int32)fun.Invoke(obj, new Object[] { "Fode" });
  });
  Console.ReadKey();

其運行結果如下所示:

c#使用dynamic類型優化反射的方法

從以上結果看出,使用dynamic使用時間為481ms,基礎反射使用時間為3063ms,CPU和時間上相差了5倍多,測試器 CodeTimer 的代碼隨后會貼出。

總結:

可以看到雖然用dynamic優化后的反射跟基礎反射的相比,效率雖然在同一個數量級上。可是基礎反射卻沒有dynamic代碼簡潔,因此建議:始終使用dynamic來簡化反射實現(前提你知道你要是實現的類型),在往后的隨筆,將會提出用ExpressionTree和Emit技術深度優化反射。

代碼下載:ConsoleApp2.rar

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/fode/p/10066852.html

延伸 · 閱讀

精彩推薦
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
主站蜘蛛池模板: 97超级碰碰人国产在线观看 | 国产成人精品免费视频大全最热 | 国产在线观看91精品 | 精品国产一级毛片 | 中文字幕精品在线播放 | 黄色网址进入 | 亚洲午夜天堂吃瓜在线 | 91热久久免费频精品黑人99 | 成人三级视频在线观看 | 看国产一级毛片 | 国产精品久久999 | 欧美一级小视频 | 国产亚洲精品久久久久久久久 | 韩国一大片a毛片 | 特级毛片免费视频 | 欧美大电影免费观看 | 亚洲视频综合网 | 免费午夜视频在线观看 | 国产99视频在线观看 | 欧美另类综合 | 亚洲成年人免费网站 | 久久久久北条麻妃免费看 | 香蕉久久久精品 | 成人毛片视频在线观看 | 天堂精品久久 | 黄色高清视频网站 | 国内精品视频饥渴少妇在线播放 | 成人福利在线播放 | 欧美日韩在线播放 | 国产正在播放 | 精品国产专区 | 91午夜少妇三级全黄 | 日韩精品久久久久久久九岛 | 依人九九宗合九九九 | 一本色道久久综合亚洲精品图片 | 中文字幕一区二区三区四区 | 中文字幕在线观看网址 | 天天夜干| 日本在线播放一区 | 视频一区二区三区在线观看 | 黄色av网站在线观看 |