2011-12-26 8 views
8

Estoy tratando de crear un mecanismo genérico similar a un patrón de fábrica.¿Puedo forzar a los descendientes a tener un constructor sin parámetros?

La fábrica será como:

public class APlugin<ActionType> where ActionType : IAction 
{ 
    // create a new action. Note: ActionType should contain 
    // an empty constructor 
    public ActionType CreateAction() 
    { 
     return Activator.CreateInstance<ActionType>(); 
    } 
} 

Descendientes de IAction podrían ocultar el constructor sin parámetros y esto hará que la fábrica falle.

+0

Dale que la nueva restricción() por lo que sólo puede utilizar el constructor, nuevo ActionType(). Pero no necesariamente útil en escenarios de plug-in. –

+1

Cuando dices "constructor vacío", ¿te refieres a un constructor que no toma parámetros? – Gabe

+0

Sí @Gabe. Exactamente – Odys

Respuesta

8

No se puede forzar un constructor vacío o cualquier tipo de constructor en los tipos derivados.

Los constructores no se heredan, pero se llaman.

Si no encadena al constructor base (utilizando la sintaxis : base()), se llamará implícitamente al constructor base predeterminado.

De Using Constructors en MSDN:

En una clase derivada, si un constructor de la clase base no se llama explícitamente usando la palabra clave base, entonces el constructor por defecto, si es que existe, se llama implícitamente.

9

Puede asegurarse de que la clase tenga un constructor sin argumentos al proporcionar la restricción genérica where T : new(). Sin embargo, afectará al tipo T. La clase contenedora no se verá afectada, por lo que puede asegurarse de que ActionType en su caso haya dicho constructor, pero no puede aplicarlo en ninguna clase heredando desde APlugin<T>.

+0

La restricción 'new()' del tipo genérico simplemente significa que debe haber un constructor público sin parámetros. No impide que los constructores con parámetros existan para el tipo restringido (o los tipos derivados). – Oded

+2

Sé lo que 'new()' hace, pero no estoy seguro de qué OP está tratando de lograr. Parece que quiere asegurarse de que 'Activator.CreateInstance ()' no fallará porque no hay constructores sin parámetros. Agregar restricción a 'ActionType' se encargará de eso. No impedirá agregar constructores con parámetros, siempre que también haya uno sin parámetros. – MagnatLU

+0

(cont.) Así que puede haber un tipo de implementación de IAction que no tenga un constructor predeterminado, pero obtendrá un error de compilación cuando trate de usarlo como tipo genérico 'ActionType' en' APlugin'. – MagnatLU

0

bastante tarde, pero creo que esto vale la pena conocer ..

Puede forzar constructores con parámetros 0 en clases no abstractas. Esta es una restricción de tipo para usar siempre que quiera aplicar esas restricciones en una estructura de clase. Requiere que especifique el tipo que implementa la interfaz que puede ser perturbador. Ese es el precio si quieres un tipo de seguridad limpia.

public interface IEmptyConstructor<TThis> where TThis : IEmptyConstructor<TThis>, new() {} 

por ejemplo una estructura Singleton

public abstract class Singleton<TThis> : ISingleton where TThis : Singleton<TThis>, new() { /* some singleton madness */ } 
Cuestiones relacionadas