Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract base class that inherits ICollection<T>

Suppose I have an abstract base class BaseTimeCollection and at least one concrete class ConcreteTimeCollection which inherits from the base class.

I would like my base class to inherit from ICollection<T>.

Inheriting from ICollection<T> requires me to provide implementations for a number of methods, including IEnumerable.GetEnumerator() and IEnumerable<T>.GetEnumerator.

I do not want to implement these methods in BaseTimeCollection - instead I would prefer to implement them individually in each of my concrete classes.

This is where I run into trouble.

The GetEnumerator methods need to be declared explicitly, because there are two of them both with the same name but different return types. However, it seems that as soon as I make the signature explicit I can no longer use the abstract modifier. Essentially I am forced to implement the GetEnumerator method in my base class.

public abstract class BaseTimeCollection : ICollection<Time>
{
    abstract IEnumerator IEnumerable.GetEnumerator();  // compile error: The modifier    'abstract' is not valid for this item
    abstract IEnumerator<Time> IEnumerable<Time>.GetEnumerator(); // compile error: The       modifier 'abstract' is not valid for this item
}

public class ConcreteTimeCollection : BaseTimeCollection
{
    IEnumerator IEnumerable.GetEnumerator()
    {
       // this is where I would like to provide my implementation for IEnumerable.GetEnumerator()
    }

    IEnumerator<Time> IEnumerable<Time>.GetEnumerator()
    {
        // this is where I would like to provide my implementation for IEnumerable<Time>.GetEnumerator()
    }
}
  1. What have I missed?

  2. Is there some way I can defer implementation of the GetEnumerator methods to the concrete classes?

like image 993
knick Avatar asked Jul 28 '11 13:07

knick


1 Answers

You can easily defer the implementation to your child classes by having the explicit implementations call protected abstract methods in your abstract class and then letting the children implement those abstract methods:

public abstract class BaseTimeCollection : ICollection<Time>
{
    protected abstract IEnumerator IEnumerable_GetEnumerator();
    protected abstract IEnumerator<Time> GenericEnumerable_GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() 
    { 
        return IEnumerable_GetEnumerator(); 
    }

    IEnumerator<Time> IEnumerable<Time>.GetEnumerator()
    {
        return GenericEnumerable_GetEnumerator();
    }
}

Sorry for the poor naming scheme...it's the best I could come up with this early in the morning.

like image 53
Justin Niessner Avatar answered Sep 28 '22 06:09

Justin Niessner