2011-07-28 14 views
6

Supongamos que tengo una clase base abstracta BaseTimeCollection y al menos una clase concreta ConcreteTimeCollection que hereda de la clase base.Clase base abstracta que hereda ICollection <T>

Me gustaría que mi clase base herede de ICollection<T>.

Heredar desde ICollection<T> requiere que proporcione implementaciones para una serie de métodos, incluidos IEnumerable.GetEnumerator() y IEnumerable<T>.GetEnumerator.

No quiero implementar estos métodos en BaseTimeCollection - en su lugar, preferiría implementarlos individualmente en cada una de mis clases concretas.

Aquí es donde me encuentro en problemas.

Los métodos GetEnumerator deben declararse explícitamente, porque hay dos de ellos con el mismo nombre pero diferentes tipos de devolución. Sin embargo, parece que tan pronto como haga explícita la firma ya no puedo usar el modificador abstracto. Esencialmente, estoy obligado a implementar el método GetEnumerator en mi clase base.

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. Qué me he perdido?

  2. ¿Hay alguna manera de diferir la implementación de los métodos GetEnumerator a las clases concretas?

+0

¿Cuál es el error de compilación que está obteniendo? –

Respuesta

6

Usted puede diferir fácilmente la ejecución de sus clases hijas por tener las implementaciones llamada explícita protegidos métodos abstractos en su clase abstracta y luego dejar que los niños poner en práctica esos métodos abstractos:

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(); 
    } 
} 

Lo siento por la mal esquema de nombres ... es lo mejor que pude hacer a esta hora de la mañana.

+0

Parece que debería hacer el truco, ¡gracias! Parece bastante obvio en retrospectiva :) – knick

+1

No es necesario tener dos implementaciones abstractas, ya que la implementación no genérica puede llamar al método abstracto genérico. – supercat

0

Antes que nada: ¿Cuál es el error de compilación que está obteniendo?

¿Necesita su clase base, tal vez sólo puede utilizar otra interfaz como:

public interface BaseTimeCollection : ICollection<Time> {} 

y luego tienen sus implementaciones implementan esa interfaz en lugar de su clase base, o tiene alguna funcionalidad común?

+0

Para el código de muestra en mi publicación, el error de compilación que obtengo es "El modificador 'resumen' no es válido para este elemento". Este error apunta a las dos declaraciones de método abstracto en la clase base.Sí, tengo alguna funcionalidad común que se ha omitido en el ejemplo. – knick

0

No es necesario implementar ambas versiones de GetEnumerator explícitamente para evitar el conflicto de nombres, por lo que a menos que exista otro requisito para que ambos sean explícitos, podría hacer que el método genérico sea implícito para que también pueda ser abstracto. Entonces, según @supercat, el método no genérico puede llamar al genérico.

public abstract class BaseTimeCollection<Time> : ICollection<Time> 
{ 
    public abstract IEnumerator<Time> GetEnumerator(); // implicit, generic and abstract 

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

    // Other ICollection methods (Add, Clear, etc) ... 
} 
Cuestiones relacionadas