IEnumerable的<>实例化为List<>但不能添加元素

时间:2014-03-03 14:39:12

标签: c# .net inheritance polymorphism

我有一个父类:

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<>。我怎样才能实现我的目标?

3 个答案:

答案 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如果这是你想要实现的,那就不会实现任何更具体的接口。