首頁 >後端開發 >C++ >為什麼在 C# 中從派生型別轉換為基本泛型型別失敗?

為什麼在 C# 中從派生型別轉換為基本泛型型別失敗?

Patricia Arquette
Patricia Arquette原創
2025-01-06 02:19:40533瀏覽

Why Does Casting from a Derived to a Base Generic Type Fail in C#?

從派生泛型類型轉換為基本泛型類型:深入研究不相容性

在C# 中,泛型類型的繼承模型通常會導致以下問題:從衍生型別轉換為基底型別。此查詢探討了潛在的複雜性以及為什麼從衍生類別到其基底類別的直接轉換可能會失敗。

轉換之謎

考慮以下程式碼片段:

public abstract class EntityBase { }
public class MyEntity : EntityBase { }

public abstract class RepositoryBase<T> where T : EntityBase { }
public class MyEntityRepository : RepositoryBase<MyEntity> { }

現在,讓我們檢查一下有問題的line:

MyEntityRepository myEntityRepo = GetMyEntityRepo(); // whatever
RepositoryBase<EntityBase> baseRepo = (RepositoryBase<EntityBase>)myEntityRepo;

運行這段程式碼,會遇到運行時異常。為什麼此轉換嘗試失敗?

通用方差:相容性的幻覺

直觀上,我們可能會假設像MyEntityRepository 這樣的派生類也是其基類的一種類型類,RepositoryBase。然而,在泛型領域,這種假設並不總是有效。

泛型變異數是指泛型型別以或多或少的衍生型別取代其型別參數的能力。不幸的是,C# 僅在某些特定場景中支援有限的變化。

在此範例中,RepositoryBase不是 MyEntityRepository 的基底類別。這是因為型別參數 T 相對於其基底型別不是協變或逆變的。

協變:單邊之旅

協變允許泛型類別引用比其基類更衍生的型別參數。在泛型類型僅使用其類型參數傳回值的某些情況下,這是允許的。然而,這裡的情況並非如此。

逆變:一場艱苦的戰鬥

另一方面,逆變允許泛型類型使用派生較少的類型參數接受值時比其基類更重要。但同樣,這在這種情況下不適用。

通用安全的保護

如果沒有通用方差,從派生類型轉換為基本類型可能會導致意外的結果行為和潛在的運行時錯誤。例如,如果 RepositoryBase類別有一個只能對 EntityBase 類型的實體進行操作的方法,將 MyEntityRepository 轉換為 RepositoryBase可能允許無效操作。

避免轉換陷阱

如果您需要在泛型類型之間進行轉換,則必須了解泛型變異數的限制。考慮引入從基底類別到衍生類別的明確轉換,或使用工廠方法或橋樑模式等替代設計模式來避免這些陷阱。

以上是為什麼在 C# 中從派生型別轉換為基本泛型型別失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn