C# 中值類型為何不支持協變或逆變?
協變和逆變的概念允許對 IEnumerable<T>
進行協變使用,接受一個超類型(例如,將 IEnumerable<string>
賦值給 IEnumerable<object>
)。但是,這種行為不適用於值類型,例如 IEnumerable<int>
。
文檔指出,此限制是由於方差僅適用於引用類型的原則。為了理解原因,讓我們深入探討裝箱的概念及其對協變和逆變的影響。
值類型和裝箱的作用
值類型直接存儲在內存中,並且沒有與其值分離的標識。當值類型賦值給引用變量時,會發生一個稱為裝箱的過程。在這個過程中,值類型被包裝在一個對象包裝器中,該包裝器包含該值並引用原始值類型的內存位置。此包裝器允許值類型被視為對象。
裝箱和方差
為了使協變起作用,CLR 必須保證在將引用類型賦值給超類型時不會發生表示更改。這是因為使用代碼不需要知道它正在操作的對象的確切類型。但是,對於值類型,沒有對象包裝器;值直接存儲在內存中。因此,當值類型賦值給引用變量時,需要進行裝箱操作。此裝箱操作會更改值的表示,引入一層間接性。
標識保持和方差
標識保持是指在將對象賦值給基類型或派生類型時,能夠保持對象相同標識的能力。在協變轉換中,CLR 要求對象的標識得以保留。但是,對於值類型,裝箱和拆箱操作可能會意外地更改對象的標識。這違反了協變轉換的標識保持特性。
因此,為了確保標識保持轉換並保持引用的有效性,CLR 僅將協變和逆變限制為引用類型。
以上是為什麼在C#中不具有價值類型的協方差或違反?的詳細內容。更多資訊請關注PHP中文網其他相關文章!