[英]Cast Collection<Derived> to Collection<Base>
在這里有另一個簡單的問題使我難以理解。
我有2節課:
namespace Assets
{
public class BaseAsset
{
// Code here
}
}
和
namespace Assets
{
public class Asset : BaseAsset
{
// Code here
}
}
我有一個從數據庫返回資產集合的函數,並且我希望另一個函數執行該函數並返回BaseAsset的集合。 我已經試過了:
public static Collection<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
{
return (Collection<BaseAsset>)AssetData.getAssets(CategoryId, UserId, CompanyId);
}
但您可以猜到,它不起作用。 如果我使用列表,則可以執行以下操作:
public static List<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
{
return AssetData.getAssets(CategoryId, UserId, CompanyId).Cast<BaseAsset>().ToList();
}
但是我更喜歡使用一個集合,任何人都可以提出一個優雅的解決方案嗎?
干杯,r3plica
這是一個非常常見的問題。 所需功能的名稱是通用協方差 ; 就是說,“如果長頸鹿是一種動物,那么長頸鹿清單就是一種動物清單”。
問題是長頸鹿清單不是動物清單。 您可以將老虎放入動物列表中,但不能將老虎放入長頸鹿列表中,因此,在需要動物列表的任何情況下都不能使用長頸鹿列表。
您應該使用IEnumerable<T>
而不是Collection<T>
的原因是,從C#4開始,如果提供的類型參數都是引用類型,則IEnumerable<T>
在T中是協變的。 也就是說,字符串序列可以用作對象序列,因為它們都是引用類型。 但是一個整數序列不能用作一個對象序列,因為一個是值類型。
之所以安全,是因為無法將老虎插入IEnumerable<Giraffe>
。
如果要簡化.ToList
,只需編寫自己的.ToCollection
擴展方法。 實現應該簡單明了-采取IEnumerable<T>
,循環遍歷,然后使用Add
將所有內容添加到集合中。
問題在於Collection<T>
和ICollection<T>
是不變的(也就是說, Collection<BaseAsset>
既不是Collection<Asset>
的子類型也不是其超類型)。
通過返回IEnumerable<BaseAsset>
或IReadOnlyList<BaseAsset>
而不是Collection<BaseAsset>
將很容易解決該問題。
也就是說,您可以編寫:
public static IEnumerable<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
{
return AssetData.getAssets(CategoryId, UserId, CompanyId);
}
強制轉換變得不必要。
一般情況下,應優先使用的接口類型(如IList<T>
IReadOnlyList<T>
ICollection<T>
或IEnumerable<T>
在具體類型( Collection<T>
或List<T>
時指定返回值和功能參數。
與其嘗試轉換為基類,不如直接提取一個接口並使用它。
由於Collection<T>
類具有以IList<T>
作為參數的構造函數,因此您始終可以執行以下操作:
Collection<BaseAsset> = new Collection<BaseAsset>(
assetList.Cast<BaseAsset>().ToList());
當然,如果您需要重用此行為,則可以進行CastToCollection擴展:
public static Collection<TResult> CastToCollection<TResult>(this IEnumerable source)
{
return new Collection<TResult>(source.Cast<TResult>().ToList());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.