2010-05-25 15 views
14

Después de un poco de programación, una de mis clases usaba genéricos de una manera que nunca antes había visto. Me gustaría obtener algunas opiniones sobre esto, si es una codificación incorrecta o no.Uso extraño de genéricos

abstract class Base<T> : where T : Base<T> 
{ 
    // omitted methods and properties. 
    virtual void CopyTo(T instance) { /*code*/ } 
} 

class Derived : Base<Derived> 
{ 
    override void CopyTo(Derived instance) 
    { 
     base.CopyTo(instance); 
     // copy remaining stuff here 
    } 
} 

¿Es este un uso correcto de los genéricos o no? Estoy pensando principalmente en la restricción para "sí mismo". A veces siento que los genéricos pueden "explotar" en otras clases donde utilizo la clase Base.

+4

En realidad no es raro, lo he visto antes ... –

+0

Para eso están los genéricos. Sin embargo, probablemente exponga una interfaz para hacerlo aún más abstracto. –

+0

¿Por qué necesita el tipo T para ser una Base ? No vi ninguna razón para eso en tu muestra, en realidad no puedo entender por qué estás usando eso, ¿es algo que me estoy perdiendo? –

Respuesta

9

Sí, esto es razonable: tengo algo similar en mi puerto Protocol Buffers (excepto que es más complicado, ya que hay dos tipos de referencias mutuas).

Tiene toda la razón sobre los genéricos que a veces terminan propagándose en la base de códigos: lo que ha hecho aquí significa que los bits de código que solo se preocupan por Derived que tienen una API adecuada no necesitan preocuparse por los genéricos .

Mi consejo es tratar de mantenerlo simple siempre que sea posible, pero en los casos en que una restricción genérica "extraña" realmente describa lo que usted desea, vaya para ello. Debe tener en cuenta que esto no fuerza uso válido aunque - usted puede fácilmente tiene:

class Banana : Base<Derived> 

y que sería válida, aunque rara y probablemente inesperada para los usuarios.

Es posible que también desee considerar el sellado Derived aquí; si deriva más, es probable que termine con un comportamiento extraño (o al menos una API impar).

+0

Jon, ¿no falló Banana: Base ? Dado que 'donde T: Base '? –

+1

@Filip Ekberg, no, funciona, ya que T = 'Derived', y' Derived' es 'Base ' –

+0

Ah, simplemente me pareció un poco extraño :) –

Cuestiones relacionadas