问题描述
我有一堂这样的课:
public class ItemList
{
[JsonProperty("items")]
public IEnumerable<Item> Items { get; set; }
}
我想初始化空列表,如下所示:
var newItemList = new ItemList
{
Items = new List<Item>()
};
但是 Items
仍然是 IEnumerable
,我不能使用 Add
或其他列表方法。
解决方法
为什么不将其声明为列表
public class ItemList
{
[JsonProperty("items")]
public List<Item> Items { get; set; }
}
List 是 IEnumerable
的扩展,因此将其声明为列表并具有所有方法是有意义的。
由于您已经声明为 public IEnumerable<Item> Items { get; set; }
,因此不会更改。
你可以这样做:
Items = new List<Item>();
甚至
ItemList itemlist = new itemlist();
itemlist.Items = new List<Item>();
((List<Item>)itemlist.Items).Add(new Item());
但是 ((List<Item>)itemlist.Items).Add(new Item());
并不安全。当您初始化为列表时它会起作用,但如果您尝试从其他 IEnumerable
类型进行转换,它将导致运行时异常。
您可以使用以下两个选项之一。
-
你可以像下面这样使用 List Initializer
var itemList = new ItemList() { Items = new List<Item>() { new Item() { Name = "One" },new Item() { Name = "Two" } } };
-
您可以完全初始化列表,然后将其分配给
Items
-
更好的方法是使用 Builder 模式,它有助于构建 https://code-maze.com/fluent-builder-recursive-generics/
中所述的ItemList
拥有 IEnumerable 可以让您实现 SOLID 原则之一,即您必须依赖抽象而不是具体的类。这意味着您可以在该属性(列表、HashSet 等...)中存储 IEnumerable 的任何实现。
如果要使用List类实现的Add方法,必须把IEnumerable转成List
var myList = newItemList.ToList<T>();
myList.Add(new T());
其中 T 是您的具体类。
,当然可以,只需投射即可:
(Items as List<Item>).Add(someItem);
可能会一直很无聊:
public class ItemList
{
private List<Item> _items - new List<Item>;
[JsonProperty("items")]
public IEnumerable<Item> Items { get => _items; private set => _items = value as List<string>; }
}
然后在类中可以使用 _items
。
我建议您将该 setter 设为私有,并将项目设置为内部类的列表;集合上需要强制转换,但如果其他人传入一个不是 List 的 IEnumerable,它将导致项目集合设置为 null。
如果你决定外部类会看到一个 IEnumerable 但你要把它作为一个列表,那么你不应该给任何使用你的类的人机会将它更改为不是一个列表..
如果您只打算设置一次列表(永远不要为新实例更改它),例如在构造函数中,然后您可以将属性设为只读