2009-02-27 21 views
6

Básicamente tengo una clase de Lista personalizada que contiene diferentes frutas. Supongamos que cada fruta tiene un número de ID que está almacenado en la lista.Genéricos o no Genéricos

¿Es mejor tener:

new AppleList(); 
new OrangeList(); 
new LemonList(); 

o

new FruitList<Fruit.Apple>(); 
new FruitList<Fruit.Orange>(); 
new FruitList<Fruit.Lemon>(); 

Aspectos a considerar:

  • Todas las ID son de tipo int.
  • El tipo de fruta no afectará la implementación de la Lista. Solo será utilizado por el cliente de la lista, como un método externo, etc.

Me gustaría utilizar el que es más claro, mejor en diseño, más rápido, más eficiente, etc. Además, si estos las 2 técnicas anteriores no son las mejores, por favor sugiera sus ideas.

EDITAR: Btw Fruit es una enumeración si no estaba claro.

+0

que está haciendo una lista de enumeraciones ?? para eso no son realmente las listas. las enumeraciones ya son una especie de lista. –

+0

Gracias, no, no una lista de enumeraciones. Solo está ahí para tipo. Todas estas listas almacenarán entradas, como 1,2,3,4. –

+1

Estoy realmente sorprendido de cuántas personas no entendieron que está almacenando una lista de enteros. –

Respuesta

3

• Todas las identificaciones son del tipo int.

• El tipo de fruta no afectará la implementación de la Lista en sí. Solo será utilizado por el cliente de la lista, como un método externo, etc.

Teniendo en cuenta estos dos hechos, no me molestaría con los genéricos. Yo pondría una propiedad normal en FruitList para indicar qué tipo de fruta es.

+0

¿Por qué debería mantener 3 listas diferentes haciendo lo mismo? La única diferencia aquí son los ids contenidos para diferentes tipos de fruta, pero no afecta el comportamiento de la lista. ¿Por qué no usar simplemente var appleList = new List () ... – Beachwalker

7

Es mucho más fácil mantener 1 lista genérica que 3 versiones no genéricas. Si realmente te gusta el nombre AppleList siempre se puede utilizar el truco para usar el nombre de una lista genérica

using AppleList=Fruit.FruitList<Fruit.Apple> 
+0

Si realmente necesita AppleList, usar un "truco" para que parezca AppleList en realidad no lo convierte en AppleList. –

+0

No conozco esta sintaxis utilizada de esta manera. ¿Y cuando digo AppleList, creará FruitList ? –

+0

@Joan sí, eso es correcto – JaredPar

9

Si utiliza los genéricos, ¿hay un propósito para crear el tipo FruitList? ¿Podrías usar List?

No habrá mucha diferencia en el rendimiento, entonces digo ¿por qué crear tres clases diferentes cuando uno haría exactamente lo mismo? Usa la solución genérica

+0

Gracias, sí FruitList es necesario para implementar nuevas interfaces y también tiene alguna funcionalidad allí que List no tiene. –

+0

¿Cómo qué? ¿No podría su funcionalidad ser servida con métodos de extensión en una lista normal? ¿Qué quiere decir con "necesario para implementar nuevas interfaces"? –

+0

No recomendaría los métodos de extensión en una clase que tenga control de. – gcores

10

Usar un combo:

public class AppleList : FruitList<Apple> { ... } 
public class OrangeList : FruitList<Orange> { ... } 
public class LemonList : FruitList<Lemon> { ... } 

poner la lógica común en la clase base de la lista:

public class FruitList<T> : List<T> 
    where T : IFruit 
{ ... } 
+0

Gracias, esto no funcionaría, creo. Porque todas las listas de frutas serán 100% iguales. Pero todavía necesito una forma de distinguirlos externamente. –

+1

Si son todos iguales, entonces usted puede simplemente tener AppleList: Lista

+0

Gracias. ¿Apple es una clase en tu caso? ¿Por qué heredar de List? Sólo me preguntaba. –

3

Reutilizar las clases de colección genéricos y la subclase sólo si va a añadir funcionalidad adicional. Mantenga la implementación de su subclase genérica si puede. Esta es la implementación menos compleja.

1

Usa la lista genérica, no tiene sentido en las listas de crating 3 y siempre es bueno mantener un nivel de abstracción. (IFruit sería una buena interfaz).

+0

IFruit es bueno para qué? No se aplicaría a INTEGERS almacenados en la lista. –

+0

¿Por qué no usar simplemente var appleList = new List (); La contención podría definirse externamente; podría crear una clase FruitList: List {Fruit Type {get; }} – Beachwalker

0

Debe asumir YAGNI a menos que lo necesite. Por lo tanto, si no necesita antyhing más de lo que obtiene en List, solo List<T>.Si por alguna razón usted tiene que anular la lista, a continuación, crear

FruitList<T> : List<T> where T : Fruit 

Si sus listas divergen y ya no polimórficos son, entonces considerar la implementación de sus listas personalizadas:

  • AppleList
  • OrangeList
  • LemonList

Prueba como mejor yo Sin embargo, puede mantener su jerarquía de herencia lo más plana posible para evitar complicar demasiado su solución.

+0

No estabas escuchando. La lista contiene enteros, no Frutos. –

+0

En realidad, no sé esto: ¿List no es una clase sellada? –

+0

La lista definitivamente no está sellada. –

1

no recomendaría la respuesta aceptada y creo que quería decir algo como esto en su lugar:

public enum Fruit 
{ 
    Apple, 
    Orange, 
    Lemon 
} 

public interface IFruitList : IList<int> 
{ 
    Fruit Type { get; } 
}; 

public class FruitList : List<int>, IFruitList 
{ 
    private readonly type; 

    FruitList(Fruit type) 
    : base() 
    { 
     this.type = type; 
    } 

    FruitList(Fruit type, IEnumerable<int> collection) 
    : base(collection) 
    { 
     this.type = type; 
    } 

    Fruit Type { return type; } 
}