最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于C#?dynamic裝箱問題

 更新時間:2022年05月18日 14:25:57   作者:yi念之間  
裝箱是將值類型轉(zhuǎn)換為類型對象或此值類型實現(xiàn)的任何接口類型的過程,裝箱和拆箱的概念是 C# 類型系統(tǒng)統(tǒng)一視圖的基礎,其中任何類型的值都可以視為對象,這篇文章主要介紹了關于C#?dynamic裝箱引發(fā)的思考,需要的朋友可以參考下

前言

前幾天在技術群里看到有同學在討論關于dynamic是否會存在裝箱拆箱的問題,我當時第一想法是"會"。至于為啥會有很多人有這種疑問,主要是因為覺得dynamic可能是因為有點特殊,因為它被稱為動態(tài)類型,可能是因為這里的動態(tài)對大家造成的誤解,認為這里的動態(tài)可以推斷出具體的類型,所以可以避免裝箱拆箱。但是事實并不是這樣,今天就一起就這個問題雖然討論一下。

裝箱拆箱

首先咱們先來看下何為裝箱拆箱,這個可以在微軟官方文檔中Boxing and Unboxing文檔中看到答案,咱們就簡單的摘要一下相關的描述

裝箱是將值類型轉(zhuǎn)換為類型對象或此值類型實現(xiàn)的任何接口類型的過程。當公共語言運行時 (CLR) 將值類型裝箱時,它會將值包裝在 System.Object 實例中并將其存儲在托管堆上。拆箱從對象中提取值類型。拳擊是隱含的;拆箱是明確的。裝箱和拆箱的概念是 C# 類型系統(tǒng)統(tǒng)一視圖的基礎,其中任何類型的值都可以視為對象。

翻譯起來會比較抽象,理解起來就是利用裝箱和拆箱功能,可通過允許值類型的任何值與Object 類型的值相互轉(zhuǎn)換,將值類型與引用類型鏈接起來。也就是值類型和引用類型相互轉(zhuǎn)換的一做橋梁,但是問題也很明顯那就是實例會存在在堆棧之前相互copy的問題,會存在一定的性能問題,所以這也一直是一個詬病。

雖然說是這樣但是也沒必要一直扣死角,畢竟很多時候程序還沒有糾結(jié)到這種程度,因為任何語言存在的各種方法中或者操作中都會有一定這種問題,所以本質(zhì)不是語言存在各種問題,而是在什么場景如何使用的問題。比如避免出現(xiàn)裝箱和拆箱的辦法也就是入概念所說的,那就是避免值類型和和引用類型之間相互轉(zhuǎn)換,但是很多時候還是避免不了的,所以也不必糾結(jié)。

探究本質(zhì)

上面講解了關于裝箱拆箱的概念,接下來咱們就來定義一段代碼看看效果,為了方便對比咱們直接對比著看一下

dynamic num = 123;
dynamic str = "a string";

想要看清本質(zhì)還是要反編譯一下生成的結(jié)果看一下的,這里我們可以借助ILSpydnSpy來看下,首先看一下反編譯回來的效果

private static void <Main>$(string[] args)
{
	object num = 123;
	object str = "a string";
	Console.ReadKey();
}

因為我是使用的是.net6的頂級聲明方式所以會生成<Main>$方法。不過從反編譯的結(jié)果就可以看出來dynamic的本質(zhì)是object,如果還有點懷疑的話可以直接查看生成的IL代碼,還是使用ILSpy工具

.method private hidebysig static 
	void '<Main>$' (
		string[] args
	) cil managed 
{
	// Method begins at RVA 0x2094
	// Header size: 12
	// Code size: 30 (0x1e)
	.maxstack 1
	.entrypoint
	.locals init (
        // 這里可以看出聲明的num和str變量都是object類型的
		[0] object num,
		[1] object str
	)

	// object obj = 123;
	IL_0000: ldc.i4.s 123
    // 這里的box說明存在裝箱操作
	IL_0002: box [System.Runtime]System.Int32
	IL_0007: stloc.0
	// object obj2 = "a string";
	IL_0008: ldstr "a string"
	IL_000d: stloc.1
	// Console.ReadKey();
	IL_000e: call valuetype [System.Console]System.ConsoleKeyInfo [System.Console]System.Console::ReadKey()
	IL_0013: pop
	// (no C# code)
	IL_0014: nop
	IL_0015: nop
	IL_0016: nop
	IL_0017: nop
	IL_0018: nop
	IL_0019: nop
	IL_001a: nop
	IL_001b: nop
	// }
	IL_001c: nop
	IL_001d: ret
} // end of method Program::'<Main>$'

通過這里可以看出dynamic的本質(zhì)確實是object,既然是object那就可以證實確實是存在裝箱操作。這個其實在微軟官方文檔Using type dynamic上有說明,大致描述是這樣的

dynamic類型是一種靜態(tài)類型,但類型為dynamic的對象會跳過靜態(tài)類型檢查。大多數(shù)情況下,該對象就像具有類型object一樣。 在編譯時,將假定類型化為dynamic的元素支持任何操作。因此,不必考慮對象是從 COM API、從動態(tài)語言(例如 IronPython)、從 HTML 文檔對象模型 (DOM)、從反射還是從程序中的其他位置獲取自己的值。但是,如果代碼無效,則在運行時會捕獲到錯誤。

從這里可以看出dynamic表現(xiàn)出來的就是object,只是dynamic會跳過靜態(tài)類型檢查,所以編譯的時候不會報錯,有錯誤的話會在運行的時候報錯,也就是我們說的是在運行時確定具體操作。這涉及到動態(tài)語言運行時,動態(tài)語言運行時(DLR)是一種運行時環(huán)境,可以將一組動態(tài)語言服務添加到公共語言運行時(CLR)。使用DLR可以輕松開發(fā)在.NET上運行的動態(tài)語言,并為靜態(tài)類型語言添加動態(tài)特征。

匿名類型

總會有人拿dynamicvar進行比較,但是本質(zhì)上來說,這兩者描述的不是一個層面的東西。var叫隱式類型,本質(zhì)是一種語法糖,也就是說在編譯的時候就可以確定類型的具體類型,也就是說var本質(zhì)是提供了一種更簡單的編程體驗,不會影響變量本身的行為。這也就解釋了為啥同一個var變量多次賦值不能賦不同類型的值,比如以下操作編譯器會直接報錯

var num = 123;
num = "123"; //報錯

如果你是用的集成開發(fā)環(huán)境的話其實很容易發(fā)現(xiàn),把鼠標放到var類型上就會顯示變量對應的真實類型?;蛘呖梢灾苯油ㄟ^ILSpy看看反編譯結(jié)果,比如聲明了var num = 123編譯完成之后就是

private static void <Main>$(string[] args)
{
	int num = 123;
	Console.ReadKey();
}

請注意這里并不是object而是轉(zhuǎn)換成了具體的類型因為123就是int類型的,嚴謹一點看一下IL代碼

.maxstack 1
.entrypoint
//聲明的int32
.locals init (
	[0] int32 num
)
// int num = 123;
IL_0000: ldc.i4.s 123
IL_0002: stloc.0

相信這里就可以看出來了dynamicvar確實也不是一個層面的東西。var是隱式類型是語法糖為了簡化編程體驗用的,dynamic則是動態(tài)語言運行時技術,編譯時轉(zhuǎn)換成object類型,因為在c#上一切都是object,然后再運行時進行具體的操作。

總結(jié)

本篇文章主要是在技術群里看到有同學在討論關于dynamic是否會裝箱引發(fā)的思考,相對來說講解的比較基礎也比較簡單。想對一個東西理解的更透徹,就要一步一步的了解它到底是什么,這樣的話就可以更好的理解和思考。也印證了那句話,你不會用或者用是因為你對它不夠了解,當你對它有足夠理解的時候,操作起來也就會游刃有余。

到此這篇關于關于C# dynamic裝箱引發(fā)的思考的文章就介紹到這了,更多相關C# dynamic裝箱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C#畫筆Pen繪制自定義線的帽子

    C#畫筆Pen繪制自定義線的帽子

    這篇文章主要介紹了C#畫筆Pen繪制自定義線的帽子,實例分析了畫筆Pen的使用技巧,需要的朋友可以參考下
    2015-06-06
  • C# 在PDF中創(chuàng)建和填充域

    C# 在PDF中創(chuàng)建和填充域

    本文主要介紹了C# 在PDF中創(chuàng)建和填充域的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • Unity使用鼠標旋轉(zhuǎn)物體效果

    Unity使用鼠標旋轉(zhuǎn)物體效果

    這篇文章主要為大家詳細介紹了Unity使用鼠標旋轉(zhuǎn)物體效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 快速了解c# 結(jié)構(gòu)體

    快速了解c# 結(jié)構(gòu)體

    這篇文章主要介紹了c# 結(jié)構(gòu)體的相關資料,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • Unity實現(xiàn)卡拉OK歌詞過渡效果

    Unity實現(xiàn)卡拉OK歌詞過渡效果

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)卡拉OK歌詞過渡效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • C#的FileSystemWatcher用法實例詳解

    C#的FileSystemWatcher用法實例詳解

    這篇文章主要介紹了C#的FileSystemWatcher用法,以實例形似詳細分析了FileSystemWatcher控件主要功能,并總結(jié)了FileSystemWatcher控件使用的技巧,需要的朋友可以參考下
    2014-11-11
  • c# 獲取CookieContainer的所有cookies函數(shù)代碼

    c# 獲取CookieContainer的所有cookies函數(shù)代碼

    這篇文章主要介紹了c# 獲取CookieContainer所有cookies的函數(shù)代碼,需要的朋友可以參考下
    2013-06-06
  • c# 獲取已安裝的打印機并調(diào)用打印文件

    c# 獲取已安裝的打印機并調(diào)用打印文件

    這篇文章主要介紹了c#如何獲取已安裝的打印機并調(diào)用打印文件,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-10-10
  • C#實現(xiàn)發(fā)送手機驗證碼功能

    C#實現(xiàn)發(fā)送手機驗證碼功能

    之前基于c#實現(xiàn)手機發(fā)送驗證碼功能很復雜,真正做起來也就那回事,不過就是一個post請求就可以實現(xiàn)的東西,今天小編把思路分享到腳本之家平臺,供大家參考下
    2017-06-06
  • C#實現(xiàn)Check Password和鎖定輸錯密碼鎖定賬戶功能

    C#實現(xiàn)Check Password和鎖定輸錯密碼鎖定賬戶功能

    C#實現(xiàn)的Check Password,并根據(jù)輸錯密碼的次數(shù)分情況鎖定賬戶:如果輸入錯誤3次,登錄賬戶鎖定5分鐘并提示X點X分后重試登錄,具體實現(xiàn)代碼感興趣的朋友跟隨小編一起看看吧
    2020-01-01

最新評論

林周县| 吉安县| 泌阳县| 平原县| 陆川县| 玉林市| 广州市| 清丰县| 平和县| 大洼县| 区。| 旬阳县| 马边| 靖安县| 龙井市| 密云县| 永和县| 扶风县| 通城县| 东山县| 长治市| 融水| 龙川县| 梨树县| 平利县| 太和县| 海兴县| 五华县| 虹口区| 祥云县| 尚志市| 百色市| 长白| 郯城县| 盐池县| 虹口区| 仁化县| 礼泉县| 山阴县| 万安县| 全州县|