将集合<Derived>转换为集合<Base>

r3p*_*ica 1 c# inheritance

这里有另一个简单的问题就是躲避我.

我有2个班:

namespace Assets
{
   public class BaseAsset
   {
       // Code here
   }
}
Run Code Online (Sandbox Code Playgroud)

namespace Assets
{
   public class Asset : BaseAsset
   {
       // Code here
   }
}
Run Code Online (Sandbox Code Playgroud)

我有一个函数从数据库返回一个Asset集合,我想要另一个函数来执行该函数并返回一个BaseAsset集合.我试过这个:

    public static Collection<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
    {
        return (Collection<BaseAsset>)AssetData.getAssets(CategoryId, UserId, CompanyId);
    }
Run Code Online (Sandbox Code Playgroud)

但正如你猜测的那样,它不起作用.如果我正在使用列表,我可以这样做:

    public static List<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
    {
        return AssetData.getAssets(CategoryId, UserId, CompanyId).Cast<BaseAsset>().ToList();
    }
Run Code Online (Sandbox Code Playgroud)

但我更愿意使用一个系列,任何人都可以想出一个优雅的解决方案吗?

干杯,r3plica

Eri*_*ert 10

这是一个非常常见的问题.您想要的功能的名称是通用协方差 ; 也就是说,"如果长颈鹿是一种动物,那么长颈鹿名单就是一种动物名单".

问题是长颈鹿名单不是一种动物名单.你可以将一只老虎放入动物名单中,但你不能将老虎放入长颈鹿名单中,因此长颈鹿名单不能用于预计会有动物名单的任何情况.

你应该使用的原因IEnumerable<T>,而不是Collection<T>是因为随着C#4,IEnumerable<T>是T中协变,只要提供的类型参数都是引用类型.也就是说,字符串序列可以用作对象序列,因为它们都是引用类型.但是一系列int不能用作对象序列,因为一个是值类型.

这是安全的原因是因为没有办法将虎插入IEnumerable<Giraffe>.