c# - 投射通用集合项目类型
问题描述
以下代码说明了我遇到的情况。真实的代码使用不同的名称并以其他方式获取值,但它们与我需要的答案相匹配。特别是在第 76-89 行(我控制的唯一行)中,我需要提取一个带有值的“ICollection”类型的变量,我不喜欢使用的任何方法。是否有另一种方法可以在不创建类“AbstractCollection”的情况下做到这一点?
namespace ConsoleApp1
{
using System.Collections.Generic;
using System.Linq;
interface IEntity
{
string Id { get; }
string Name { get; }
}
class Entity : IEntity
{
public Entity(string id, string name)
{
Id = id;
Name = name;
}
public string Id { get; }
public string Name { get; }
}
interface ICollection<TGeneric>
{
IEnumerable<TGeneric> Items { get; }
}
class Collection<TGeneric> : ICollection<TGeneric> where TGeneric : Entity, IEntity
{
public IEnumerable<TGeneric> Items { get; set; }
}
class AbstractCollection<TConcrete, TAbstract> : ICollection<TAbstract> where TAbstract : class, IEntity
{
public AbstractCollection(ICollection<TConcrete> collection)
{
this._Items = new List<TAbstract>();
if (collection?.Items != null)
{
foreach (TConcrete concreteItem in collection.Items)
{
TAbstract abstractItem = concreteItem as TAbstract;
this._Items.Add(abstractItem);
}
}
}
public IEnumerable<TAbstract> Items
{
get { return this._Items; }
set { this._Items = value?.ToList(); }
}
private IList<TAbstract> _Items { get; set; }
}
class EntityCollection : Collection<Entity>
{
public EntityCollection()
{
var items = new List<Entity>()
{
new Entity("1", "Name1"),
new Entity("2", "Name2"),
new Entity("3", "Name3")
};
Items = items;
}
}
class Context
{
public Context()
{
var concreteItems = new EntityCollection();
// I can modify from this line to the end of the method but not any code before.
// I expected values in "list1" but is null.
var list1 = concreteItems as ICollection<IEntity>;
var list2 = concreteItems as ICollection<Entity>;
var abstractItems = new List<IEntity>();
foreach (Entity concreteItem in concreteItems.Items)
{
IEntity abstractItem = concreteItem as IEntity;
abstractItems.Add(abstractItem);
}
// Why "list3" is null?
var list3 = abstractItems as ICollection<IEntity>;
// I want to avoid class "AbstractCollection"
var list4 = new AbstractCollection<Entity, IEntity>(list2);
// Finally "list5" has value in the way I want it.
var list5 = list4 as ICollection<IEntity>;
}
}
class Program
{
static void Main(string[] args)
{
var context = new Context();
}
}
}
解决方案
解决方案的协方差指南:
interface ICollection<out TGeneric>
{
IEnumerable<TGeneric> Items { get; }
}
推荐阅读
- python - python pip的令人难以置信的奇怪错误消息
- python - 如何将 X_test 从 (57,) 稍微修改为 (57, 1)
- r - 在 R 中按列拆分数据帧
- python - 如何通过计算列表中的相关项目来更新实例列表?
- c# - 消息:遇到致命错误。在“C:\Program Files\dotnet”中找不到执行应用程序所需的库“hostpolicy.dll”
- javascript - PWA Firebase 推送通知“此站点已在后台更新”
- python - 带有 python 的 Google 工作表
- mongodb - $in 运算符是否有一些内置的记忆功能
- php - 发布 JSON 数据时出现 PHP 数组到字符串转换错误
- spring-kafka - Spring Kaka - 从头开始寻找偏移量