真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C#中ValueTuple的原理是什么

本篇文章為大家展示了C#中ValueTuple的原理是什么,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

公司主營(yíng)業(yè)務(wù):網(wǎng)站制作、網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出大觀免費(fèi)做網(wǎng)站回饋大家。

json 轉(zhuǎn)換

先創(chuàng)建一個(gè)項(xiàng)目,然后安裝 Json 解析,使用下面的代碼,在運(yùn)行之前,先猜一下,下面的代碼會(huì)出現(xiàn)什么

   var foo = (name: "lindexi", site: "blog.csdn.net/lindexi_gd");
   var str = JsonConvert.SerializeObject(foo);

實(shí)際上輸出的是 {"Item1":"lindexi","Item2":"blog.csdn.net/lindexi_gd"}

C#中ValueTuple的原理是什么

那么剛才的命名在哪?

如果想知道,那么請(qǐng)看 ValueTuple 的原理

原理

先來(lái)寫一段代碼,編譯之后對(duì)他反編譯,看一下他是怎么做的

  static void Main(string[] args)
  {
   var foo = Foo();
   var str = JsonConvert.SerializeObject(foo);
   Console.WriteLine(str);
  }

  static (string name, string site) Foo()
  {
   return (name: "lindexi", site: "blog.csdn.net/lindexi_gd");
  }

不需要安裝反編譯軟件,可以使用這個(gè)網(wǎng)站拿到反編譯

可以看到Foo被編譯為 TupleElementNames 特性的兩個(gè)字符串

 [return: TupleElementNames(new string[]
 {
  "name",
  "site"
 })]
 private static ValueTuple Foo()
 {
  return new ValueTuple("lindexi", "blog.csdn.net/lindexi_gd");
 }

所以實(shí)際上代碼是 ValueTuple 不是剛才定義的代碼,只是通過(guò) TupleElementNames 讓編譯器知道值,所以是語(yǔ)法糖。

IL 代碼是

private hidebysig static valuetype [mscorlib]System.ValueTuple`2 
 Foo() cil managed 
 {
 .param [0] 
 .custom instance void [mscorlib]System.Runtime.CompilerServices.TupleElementNamesAttribute::.ctor(string[]) 
  = (
  01 00 02 00 00 00 04 6e 61 6d 65 04 73 69 74 65 // .......name.site 這里就是 return: TupleElementNames 的命名
  00 00           // ..
  )
 .maxstack 2
 .locals init (
  [0] valuetype [mscorlib]System.ValueTuple`2 V_0
 )

 // [20 9 - 20 10]
 IL_0000: nop   

 // [21 13 - 21 72]
 IL_0001: ldstr  "lindexi"
 IL_0006: ldstr  "blog.csdn.net/lindexi_gd"
 IL_000b: newobj  instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0/*string*/, !1/*string*/)
 IL_0010: stloc.0  // V_0
 IL_0011: br.s   IL_0013

 // [22 9 - 22 10]
 IL_0013: ldloc.0  // V_0
 IL_0014: ret   
 }

這個(gè)特性只有編譯器可以用,不可以在代碼使用。

在上面的解釋,實(shí)際上 IL 不知道存在定義的命名,所以不可以通過(guò)這個(gè)方法獲得值。

動(dòng)態(tài)類型獲得值

如果希望使用動(dòng)態(tài)類型獲得值,那么下面的代碼實(shí)際上會(huì)運(yùn)行出現(xiàn)異常

  static void Main(string[] args)
  {
   dynamic foo = Foo();
   Console.WriteLine(foo.name);
  }

  static (string name, string site) Foo()
  {
   return (name: "lindexi", site: "blog.csdn.net/lindexi_gd");
  }

運(yùn)行出現(xiàn) RuntimeBinderException 異常,因?yàn)闆]有發(fā)現(xiàn) name 屬性

實(shí)際上對(duì)比下面匿名類,也就是很差不多寫法。

  dynamic foo = new { name = "lindexi", site = "blog.csdn.net/lindexi_gd" };
   Console.WriteLine(foo.name);

運(yùn)行是可以的,所以在使用動(dòng)態(tài)類型,請(qǐng)不要使用 ValueTuple ,如果需要使用,那么請(qǐng)知道有存在找不到變量異常,而且是在運(yùn)行才出現(xiàn)異常。

性能提升

如果使用 ValueTuple 編程會(huì)有一些優(yōu)點(diǎn),性能是其中之一。而且對(duì)于異步編程,使用 ValueTuple 可以繼續(xù)使用 await 的方法。

假如有一個(gè)方法需要返回 5 個(gè)參數(shù),那么以前的做法有三個(gè)方法,第一個(gè)方法是使用 out 的方法,第二個(gè)方法是使用 Tuple ,第三個(gè)方法是定義一個(gè)臨時(shí)的類。

如果使用了 out 的方法,那么這個(gè)方法就不可以繼續(xù)使用異步 await 的方法,因?yàn)?await 需要做出狀態(tài)機(jī),參見我寫的await原理。如果使用 Tuple ,或這定義一個(gè)臨時(shí)的類,就會(huì)出現(xiàn)性能的問題。

從上面的原理,已經(jīng)告訴大家,ValueTuple 是值類型,而 Tuple 或定義的一個(gè)類不是值類型。編譯器的優(yōu)化是讓 ValueTuple 分配在棧,對(duì)于普通的類分配在堆空間。如果一個(gè)類分配到堆空間,那么就需要使用垃圾回收才可以清理空間。而分配到棧就不需要使用垃圾回收,使用完成就清空棧,效率比堆空間大。

但是使用棧空間需要注意,棧空間是很小的,如果使用了大量棧空間可能會(huì)出現(xiàn)堆棧gg。因?yàn)榭紤]到部分剛?cè)腴T的小伙伴,所以我就需要多說(shuō)一些,上面說(shuō)的 ValueTuple 使用了??臻g需要小心??臻g不足,和你存放的值的關(guān)系不大,而是和定義的 ValueTuple 數(shù)量有關(guān),這個(gè)數(shù)量是非常大的。但是在遞歸方法中,本來(lái)是剛好空間足夠的,在使用了 ValueTuple 可能就不夠了。

使用 ValueTuple 可以繼續(xù)使用異步,而且不需要垃圾回收,性能比Tuple高,所以建議在多返回參數(shù)使用 ValueTuple,而不是定義一個(gè)類。

其他需要知道的

不要隨便定義一個(gè)看不懂的值

實(shí)際上下面的代碼,編譯是可以通過(guò)

(int x, (int y, (float a, float b))[] c) f1

但是這個(gè)值,在看的時(shí)候,幾乎說(shuō)不出他的屬性

第二個(gè)需要知道的,ValueTuple 是值類型,所以他的默認(rèn)值不是 null 而是 default(xx),在C# 7.2 支持使用關(guān)鍵字,所以不需要去寫 defalut(xx,xx)

上述內(nèi)容就是C#中ValueTuple的原理是什么,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


分享文章:C#中ValueTuple的原理是什么
轉(zhuǎn)載來(lái)源:http://weahome.cn/article/pjsggg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部