由于各种原因,我已经实现了自己的集合类。
如何避免ItemCollection resultCollection = (ItemCollection)list;
上的投射失败?我是从List<T>
继承的,所以我不能演员吗?我可以修改BaseEntityCollection
以便能够执行此操作吗?
static class Program
{
static void Main()
{
ItemCollection collection = new ItemCollection();
Item item = new Item();
item.ID = 1;
item.Name = "John";
collection.Add(item);
List<Item> list = collection.FindAll(x => x.ID == 1 && x.Name == "John");
ItemCollection resultCollection = (ItemCollection)list; // It's breaking here
}
}
public class ItemCollection : BaseEntityCollection<Item>
{
}
public class Item : BaseEntity
{
public int ID { get; set; }
public string Name { get; set; }
}
public abstract class BaseEntityCollection<T> : List<T>, IEnumerable<T> where T : BaseEntity, new()
{
}
public abstract class BaseEntity
{
}
我知道我可以在FindAll
上单独实施ItemCollection
但我想利用List<T>
上提供的所有方法。
我也知道我可以做list.ForEach(resultCollection.Add);
。但这意味着要重复迭代这个我想避免的收藏。
答案 0 :(得分:3)
只需更改构造函数,以便可以使用List<Item>
集合对其进行初始化。这允许您使用另一个集合初始化项集合:
static class Program
{
static void Main()
{
ItemCollection collection = new ItemCollection();
Item item = new Item();
item.ID = 1;
item.Name = "John";
collection.Add(item);
List<Item> list = collection.FindAll(x => x.ID == 1 && x.Name == "John");
ItemCollection resultCollection = new ItemCollection(list);
}
}
public class ItemCollection : BaseEntityCollection<Item>
{
//Allow default constructor
public ItemCollection() { }
//Construct with a list collection
public ItemCollection(IEnumerable<Item> collection)
: base(collection)
{
}
}
public class Item : BaseEntity
{
public int ID { get; set; }
public string Name { get; set; }
}
public abstract class BaseEntityCollection<T> : List<T>, IEnumerable<T> where T : BaseEntity, new()
{
//Still be able to create blank items
public BaseEntityCollection() { }
public BaseEntityCollection(IEnumerable<T> collection)
: base(collection)
{
}
}
public abstract class BaseEntity
{
}
为了避免重复列表两次,我会更改以下内容:
List<Item> list = collection.FindAll(x => x.ID == 1 && x.Name == "John");
到
var list = collection.Where(x => x.ID == 1 && x.Name == "John");
哪些会延迟加载您的列表(各种各样),但只有当您从中创建新的ItemCollection
时,它才会迭代您的集合。
答案 1 :(得分:1)
增加已经很好的答案。你问:
我是否继承了List,所以我不能投出?
是和否。
您的特定强制转换在编译时工作,但不在运行时工作。
Casting是告诉编译器的一种方式,&#34;相信我。这将在运行时工作。&#34;
在运行时,只有当Base
内的基础对象实际上是Descendant
类型的对象时,我们才能从Base
类转换为Descendant
类。 / p>
例如,请记住string
来自object
,这里说明了您的演员在运行时失败的原因。
// builds but fails at runtime
object o1 = new object();
string s1 = (string)o1;
// builds and works at runtime
// because o2 is a string in object's clothing
object o2 = (object)"";
string s2 = (string)o2;
答案 2 :(得分:0)
ItemCollection resultCollection = new ItemCollection();
resultCollection.AddRange(collection.Where(x => x.ID == 1 && x.Name == "John"));
如果你没有使用AddRange扩展方法,那就去做吧。
void AddRange<T>(this ItemCollection c, IEnumerable<T> items) => foreach(T i in items) c.Add(i);