簡體   English   中英

演員集 <Derived> 到收藏 <Base>

[英]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.

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