簡體   English   中英

為什么`IEnumerable<int> ` 不是 `IEnumerable<object> `?<div id="text_translate"><p> IEnumerable<T>接口是協變的,因此IEnumerable<string>是IEnumerable<object> 。 但是為什么IEnumerable<int><em><strong>不是</strong></em>IEnumerable<object>而int是object ?</p></div></object></int>

[英]Why `IEnumerable<int>` is not `IEnumerable<object>`?

IEnumerable<T>接口是協變的,因此IEnumerable<string>IEnumerable<object> 但是為什么IEnumerable<int>不是IEnumerable<object>intobject

只有在類型參數之間存在隱式引用標識轉換時,才支持像這樣的變體轉換。 正如規范所說:

類型T<Aᵢ, ..., Aᵥ>可以變體轉換為類型T<Bᵢ, ..., Bᵥ>如果T是接口或使用變體類型參數T<Xᵢ, ..., Xᵥ> ,並且對於每個變體類型參數Xᵢ以下之一成立:

  • Xᵢ是協變的,存在從AᵢBᵢ的隱式引用或身份轉換
  • Xᵢ是逆變的,存在從BᵢAᵢ的隱式引用或身份轉換
  • Xᵢ是不變的,存在從AᵢBᵢ的身份轉換

intobject之間既沒有引用也沒有身份轉換,只有裝箱轉換。

您可能想知道隱式引用和身份轉換有什么特別之處,以至於它們允許差異轉換。 好吧,這些轉換根本不需要運行時做任何事情!

例如,從string轉換為object純粹是編譯時的事情。 無需對表示string的位進行任何操作,即可將其轉換為object 畢竟,每個string都是object

因此,從IEnumerable<string>轉換為IEnumerable<object>也很簡單——運行時不需要做任何事情。

但是,對於intobject的轉換,情況並非如此。 因為int是值類型, object是引用類型。 為了維護這些語義,運行時需要圍繞該int創建一個引用類型包裝器以便進行轉換,“裝箱”它。

這意味着如果運行時想要將IEnumerable<int>轉換為IEnumerable<object> ,它不能只是“什么都不做”。 您希望從IEnumerable中獲取引用類型,而不是值類型,那么“裝箱”何時以及如何發生? 一般來說,這應該在何時以及如何發生,而不僅僅是在IEnumerable<T>的情況下?

我相信這在理論上都可以被弄清楚、設計和實現,但它肯定不會像隱式引用轉換那樣微不足道。 事實上,我認為它會復雜得多,並且需要對語言和運行時進行非常劇烈的更改,這可能是未實現的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM