首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Collection<Derived>转换为Collection<Base>

将Collection<Derived>转换为Collection<Base>
EN

Stack Overflow用户
提问于 2012-12-31 23:00:05
回答 5查看 1.5K关注 0票数 1

这里有另一个我想不到的简单问题。

我有两节课:

代码语言:javascript
复制
namespace Assets
{
   public class BaseAsset
   {
       // Code here
   }
}

代码语言:javascript
复制
namespace Assets
{
   public class Asset : BaseAsset
   {
       // Code here
   }
}

我有一个从数据库返回资产集合的函数,我希望另一个函数执行该函数并返回一个BaseAsset集合。我已经尝试过了:

代码语言:javascript
复制
    public static Collection<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
    {
        return (Collection<BaseAsset>)AssetData.getAssets(CategoryId, UserId, CompanyId);
    }

但正如你所猜到的,它不起作用。如果我使用列表,我可以这样做:

代码语言:javascript
复制
    public static List<BaseAsset> GetCategoryAssets(int CategoryId, string UserId, string CompanyId)
    {
        return AssetData.getAssets(CategoryId, UserId, CompanyId).Cast<BaseAsset>().ToList();
    }

但我更喜欢使用集合,有谁能想出一个优雅的解决方案吗?

干杯,r3plica

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-01-01 00:58:54

这是一个非常常见的问题。您需要的特征的名称是通用协方差;也就是说,“如果长颈鹿是一种动物,那么长颈鹿列表就是一种动物列表”的特征。

问题是长颈鹿的名单并不是动物的名单。您可以将老虎放入动物列表,但不能将老虎放入长颈鹿列表,因此长颈鹿列表不能用于需要动物列表的任何上下文中。

应该使用IEnumerable<T>而不是Collection<T>的原因是,从C# 4开始,如果提供的类型参数都是引用类型,IEnumerable<T>在T中是协变的。也就是说,字符串序列可以用作对象序列,因为两者都是引用类型。但是int序列不能用作对象序列,因为其中一个是值类型。

之所以安全,是因为无法将老虎插入到IEnumerable<Giraffe>__中。

票数 11
EN

Stack Overflow用户

发布于 2012-12-31 23:03:49

如果您想要.ToList的易用性,只需编写您自己的.ToCollection扩展方法。实现应该很简单--获取一个IEnumerable<T>,循环遍历它,并使用Add将所有内容添加到一个集合中。

票数 2
EN

Stack Overflow用户

发布于 2012-12-31 23:04:47

问题是Collection<T>ICollection<T>是不变的(也就是说,Collection<BaseAsset>既不是Collection<Asset>的子类型,也不是父类型)。

通过返回IEnumerable<BaseAsset>IReadOnlyList<BaseAsset>而不是Collection<BaseAsset>,这个问题将很容易解决。

也就是说,你可以这样写:

代码语言:javascript
复制
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>)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14103082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档