2010-09-08 11 views
5

Estoy trabajando en un motor que debe ser configurable por el usuario (no el usuario final, el usuario de la biblioteca) para usar diferentes componentes. Por ejemplo, digamos que la clase Drawer debe tener un ITool, Pencil o Brush, y un IPattern, Plain o Mosaic. Además, digamos que un Brush debe tener un IMaterial de cualquiera Copper o WoodUso de genéricos en una clase no similar a una colección

Digamos que el efecto de la elección de Pencil o Brush es realmente muy distintas, y lo mismo pasa con el tipo IPattern. ¿Sería una mala idea para codificar la clase Drawer con conceptos genéricos como esto:

public class Drawer<Tool, Pattern> where Tool: ITool where Pattern : IPattern { ... } 
public class Brush<Material> where Material : IMaterial { ... } 

Se podría entonces utilizar esa clase como:

Drawer<Pencil, Mosaic> FirstDrawer = new Drawer<Pencil, Mosaic>(); 
Drawer<Brush<Copper>, Mosaic> SecondDrawer = new Drawer<Brush<Copper>, Mosaic>(); 

mayoría Solía ​​genérico para colecciones y tal y refugio' Ver realmente genéricos utilizados para ese tipo de cosas. ¿Debería?

Respuesta

3

Realmente no tiene sentido utilizar genéricos a menos que el motor que está creando tenga métodos con argumentos o tipos de devolución del tipo genérico. Es decir. que se puede esperar que haya una propertie y métodos como

public <Material> Material { get; } 
public void Draw(<Tool> pen); 

(estoy actualmente en un modo Java así que por favor corregir la sintaxis de C#, si mal!)

De lo que puedo decir por el ejemplo que está solo usando genéricos para el constructor de las clases. Dado que confía en las interfaces en su implementación, el uso de genéricos en realidad no agrega valor.

Quizás estoy equivocado, pero los genéricos son en realidad para el tipo de seguridad revisado en tiempo de compilación y para evitar una gran cantidad de (de riesgo) tipo de fundición.

+0

Gracias, la parte sobre "a menos que el motor que está creando tenga métodos con argumentos o tipos de retorno del tipo genérico "realmente me ayudó a darme cuenta de lo inútil que hubiera sido usar genéricos en ese caso". Claro que funcionaría usando genéricos, pero sería usar genéricos solo para usar genéricos :-P – Tipx

2

Podría funcionar, pero depende de si va a ser diferente a pasar un ITool/IPattern en el constructor. En depende en parte de la conveniencia, y en parte de si hace algo interesante con los parámetros de plantilla (por ejemplo, new ellos).

Para ser honesto, el ejemplo dado hace no salto a la mente como una buena opción para los genéricos - no se puede convenientemente tener un conjunto de cepillos, por ejemplo (a menos que tenga una abstracción adicional - tal vez IBrush - no mostrado).

Los winforms estándar (system.drawing.dll) lo hacen a través de propiedades estáticas, como Pens.Red, Brushes.Blue (para un pincel sólido básico). ¿Quizás te inspires un poco? o tal vez no. Depende de usted.

+0

De hecho, no es un "Cajón" en absoluto, es un simple motor de colisión 2D :-) – Tipx

2

En esta situación, preferiría la composición a los genéricos. Me imagino que mientras que la herramienta será responsabilidad del cajón, el patrón será responsabilidad de la herramienta.

public class Drawer 
{ 
    private ITool _tool; 

    public Drawer(ITool tool, IPattern pattern) 
    { 
     _tool = new Tool(pattern); 
    } 
    ... 
} 

public class Tool : ITool 
{ 
    private IPattern _pattern; 

    public Tool(IPattern pattern) 
    { 
     _pattern = pattern; 
    } 
    ... 
} 
Cuestiones relacionadas