我有一个父类:
public abstract class ObjectCollection
{
protected IEnumerable<MyObject> Objects;
public ObjectCollection()
{
LoadObjects();
}
}
继承自它的子类:
public class PublicationCollection : ObjectCollection
{
public PublicationCollection() : base() { }
protected override void LoadObjects()
{
this.Objects = new List<PublicationObject>();
this.Objects.Add(new PublicationObject("Example"));
}
}
PublicationObject
继承自MyObject
。
行this.Objects.Add(new PublicationObject("Example"));
抛出错误,因为编译器将其视为IEnumerable
,尽管我已将其实例化为List<>
。我怎样才能实现我的目标?
答案 0 :(得分:2)
将对象声明为IEnumerable。 虽然您使用List&lt;&gt;初始化它对于编译器,它仍然是IEnumerable。
您可以在代码中修复所提供的示例:
protected override void LoadObjects()
{
var list = new List<PublicationObject>();
list.Add(new PublicationObject("Example"));
this.Objects = list;
}
班级以外的客户不会知道该属性是具体列表,也无法使用List&lt;&gt;的方法。除非转换为List&lt;&gt;
ObjectCollection oc = ...
((List<<PublicationObject>) oc.Objects).Add(...);
由于您将该类命名为A集合,我怀疑您是否希望允许客户端直接将项目附加到列表中。我专门的方法Add()是这里的方法。也许现在不是很明显,但将来会保护你: - )
命名表明这是一个集合,所以最好使你的ObjectCollection实现ICollection
。由于命名您的班级的未来用户期望收集约定。
答案 1 :(得分:1)
因为this.Objects
即公开为IEnumerable<T>
,所以可能不是列表。
如果您知道这是一个List,您可以直接投射它:
((List<PublicationObject>)this.Objects).Add(new PublicationObject("Example"));
但如果不是列表并在运行时抛出异常,则会冒风险。
由于这是完全相同的方法,只需创建一个List
变量并使用它:
protected override void LoadObjects()
{
var list = new List<PublicationObject>();
list.Add(new PublicationObject("Example"));
this.Objects = list
}
或者更好的是,如果您需要将其公开为列表(或您可以添加的某个集合),请将其声明为其他类型,例如ICollection<MyObject>
:
protected ICollection<MyObject> Objects;
答案 2 :(得分:0)
您似乎需要在Objects
方法中向PublicationCollection.LoadObjects()
添加项目。因此,首先在适当类型的变量中存储对列表的引用,稍后将该变量分配给Objects
字段:
protected override void LoadObjects()
{
var objectsList = new List<PublicationObject>();
objectsList.Add(new PublicationObject("Example"));
this.Objects = objectsList;
}
类接口保持不变(即Objects
仍然是IEnumerable<PublicationObject>
),ObjectCollection
的其他子类仍然可以将类型的实例分配给Objects
如果这是你想要实现的,那就不会实现任何更具体的接口。