[英]C#; InvalidCastException, what´s wrong?
我想將列表的對象轉換為它的子類。 為此,我使用Casting 填充 List<BaseClass> 到 List<ChildClass>
現在,當我執行代碼時,我總是在 System.Core.dll 中得到一個 InvalidCastException ""The Object Item cannot be cast to SubItem "
[Serializable]
public class SubItem: Item
{
public SubItem(int id) : base( id)
{
}
}
public getStuff(int id){
//where the Error is thrown
//Inventory has Items in it, furthermore atm Inventory is definitely not empty, but could be later on
var items = Inventory.FindAll(x=> x.id==id).Cast<SubItem>().ToList();
}
項目來自 API,我無法在那里更改任何內容。 項目繼承自 IEquatable。
LINQ 肯定可以正常工作,但是當我投射時出現錯誤。 我做錯了什么?
我將假設您的財產Inventory
是泛型類型Item
(例如: ICollection<Item>
)的強類型集合/列表/IEnumerable。
如果一項或多項不屬於泛型參數中指定的類型,則在調用Cast
時將發生InvalidCastException
。 請參閱 Microsoft 頁面Enumerable.Cast中的詳細信息。 為了解決這個問題,您只需要檢索該類型的項目,這些項目將在過濾器期間對它們執行強制轉換。 這可以通過Enumerable.OfType來完成。 然后您的代碼變為:
var items = Inventory.FindAll(x=> x.id==id).OfType<SubItem>().ToList();
如果一個元素無法轉換為 TResult 類型,則此方法將引發異常。 要僅獲取那些可以強制轉換為 TResult 類型的元素,請使用 OfType 方法而不是 Cast(IEnumerable)。
根據這些評論進行編輯
確定返回的所有項目都是Item
而不是SubItem
類型。 這解釋了異常。
...說列表由項目組成,這就是為什么我想將它們向下轉換為子項目。
您在問題中發布的繼承層次結構是System.Object
-> Item
-> SubItem
。 (我包括 Object ,因為我假設我們正在處理引用類型,並且所有東西最終都繼承自 System.Object )。 這意味着SubItem
可以轉換為Item
或System.Object
, Item
實例可以轉換為System.Object
。 然而,逆是不正確的,你不能投出圖表。 System.Object
的實例不能成為Item
並且Item
不能成為SubItem
。
擁有一個通用的List<Item>
很好,它可以包含類型SubItem
或Item
或任何派生自Item
東西。 但同樣,您不能將Item
的實例轉換為SubItem
。
如果這還不清楚,那么我建議您閱讀有關繼承和多態的一些內容,這是一個不同的主題,但如果您想知道為什么使用繼承以及是什么使它成為如此出色的抽象工具,這也非常重要。
可能是您列表中的某些項目不是派生類類型,您應該能夠在調試器中看到這一點。 另外,正如有人指出的那樣,您可能必須在進行轉換之前從數據庫中取回數據,因此 linq 提供程序可能無法為您執行此操作。
因此,您可以嘗試以下任一方法:
var items = Inventory.FindAll(x=> x.id==id).OfType<SubItem>().ToList();
var items = Inventory.FindAll(x=> x.id==id).ToList().Cast<SubItem>().ToList();
var items = Inventory.FindAll(x=> x.id==id).ToList().OfType<SubItem>().ToList();
假設 Inventory 包含一個“Item”列表,並且您想獲得一個“SubItem”列表,將您的行替換為:
var items = Inventory.Where(x => x.id == id).Select(x => new SubItem(x.id)).ToList();
因此,第一部分將為您提供符合您條件的項目,第二部分將為每個項目創建一個新的子項目並為您提供它們的列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.