Question

I have a parent class:

public abstract class ObjectCollection
{
   protected IEnumerable<MyObject> Objects;

   public ObjectCollection()
   {
      LoadObjects();
   }
}

And a child class that inherits from it:

public class PublicationCollection : ObjectCollection
{
   public PublicationCollection() : base() { }

   protected override void LoadObjects() 
   {
      this.Objects = new List<PublicationObject>();
      this.Objects.Add(new PublicationObject("Example"));
   }
}

PublicationObject inherits from MyObject.

The line this.Objects.Add(new PublicationObject("Example")); throws an error because the compiler is treating it as an IEnumerable, though I have instantiated it as a List<>. How can I achieve what I want?

Was it helpful?

Solution

Objects is declared as a IEnumerable. Although you initialize it with a List<> to the compiler it still is an IEnumerable.

You can fix it in your code for the provided example:

protected override void LoadObjects() 
   {
      var list = new List<PublicationObject>();
      list.Add(new PublicationObject("Example"));
      this.Objects = list;
   }

The clients outside of the class will not know that the property is a concrete list and will not be able to use the methods of List<> unless casted to List<>

ObjectCollection oc = ...
((List<<PublicationObject>) oc.Objects).Add(...);

Since you named the class as A collection, I doubt that you want to allow clients appending items to the list directly. I dedicated method Add() is the way to go here. Perhaps not obvious for now, but will safe you in the future :-)

Naming suggests that is a collection so it would be even better to make your ObjectCollection implement ICollection. Due to naming future users of your class expect Collection conventions.

OTHER TIPS

because this.Objects ie exposed as an IEnumerable<T>, so it could be something other than a list.

If you know it's a List you could just cast it:

((List<PublicationObject>)this.Objects).Add(new PublicationObject("Example"));

but you run the risk if it not being a list and throwing an exception at runtime.

Since this is all in the same method just create a List variable and use it:

protected override void LoadObjects() 
{
   var list = new List<PublicationObject>();
   list.Add(new PublicationObject("Example"));
   this.Objects = list
}

Or better, if you need it to be exposed as a list (or some collection you can add to), declare it as some other type, like ICollection<MyObject>:

protected ICollection<MyObject> Objects;

You seem to be needing the capability of adding items to Objects in the PublicationCollection.LoadObjects() method. Therefore, first store a reference to your list in an appropriately typed variable, later on assign that variable to the Objects field:

protected override void LoadObjects() 
{
    var objectsList = new List<PublicationObject>();
    objectsList.Add(new PublicationObject("Example"));
    this.Objects = objectsList;
}

The class interface remains the same like this (i.e. Objects will still be an IEnumerable<PublicationObject>), and other subclasses of ObjectCollection can still assign instances of types to Objects that do not implement any more specific interface, if that is what you are trying to achieve.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top