Pregunta

En un programa C #, tengo una clase base abstracta con un estático " Crear " método. El método Create se usa para crear una instancia de la clase y almacenarla localmente para su uso posterior. Como la clase base es abstracta, los objetos de implementación siempre se derivarán de ella.

Quiero poder derivar un objeto de la clase base, llamar al método de creación estático (implementado una vez en la clase base) a través de la clase derivada y crear una instancia del objeto derivado.

¿Hay alguna instalación dentro del lenguaje C # que me permita llevar esto a cabo? Mi posición de respaldo actual es pasar una instancia de la clase derivada como uno de los argumentos a la función Crear, es decir:

objDerived.Create(new objDerived(), "Arg1", "Arg2");
¿Fue útil?

Solución

Intente usar genéricos:

public static BaseClass Create<T>() where T : BaseClass, new()
{
    T newVar = new T();
    // Do something with newVar
    return T;
}

Ejemplo de uso:

DerivedClass d = BaseClass.Create<DerivedClass>();

Otros consejos

Resumen

Hay dos opciones principales. La mejor y más nueva es usar genéricos, la otra es usar la reflexión. Le proporciono ambos en caso de que necesite desarrollar una solución que funcione antes de .NET 2.0.

Genéricos

abstract class BaseClass
{
  public static BaseClass Create<T>() where T : BaseClass, new()
  {
    return new T();
  }
}

Dónde estaría el uso:

DerivedClass derivedInstance = BaseClass.Create<DerivedClass>();

Reflexión

abstract class BaseClass
{
  public static BaseClass Create(Type derivedType)
  {
    // Cast will throw at runtime if the created class
    // doesn't derive from BaseClass.
    return (BaseClass)Activator.CreateInstance(derivedType);
  }
}

Dónde estaría el uso (dividido en dos líneas para facilitar la lectura):

DerivedClass derivedClass
    = (DerivedClass)BaseClass.Create(typeof(DerivedClass));

¿Desea crear una nueva instancia de derivada desde dentro de otra instancia de derivada, utilizando un método de fábrica estático en la clase base abstracta? si es así, me pregunto por qué ... pero ...

 public abstract class MyBase
 {
    public static T GetNewDerived<T>() where T : MyBase, new()
    {
        return new T();
    }    
 }
 public class DerivedA : MyBase
 {
    public static DerivedA GetNewDerived()
    {
        return GetNewDerived<DerivedA>();
    }
 }

 public class DerivedB : MyBase
 {
    public static DerivedB GetNewDerived()
    {
        return GetNewDerived<DerivedB>();
    }
 }     

¿Es esto lo que quieres?

Parece que necesita hacer que el método Create () sea abstracto. Y una vez que lo haga, podría cambiarle el nombre y convertirlo también en el constructor. Entonces puede tener un método Init () diferente al que llama después de que se construye el objeto si es necesario, y los efectos normales de polimorfismo se encargarán de las cosas.

No puede hacerlo sin información externa; ya sea el tipo de la clase derivada, una instancia de la misma o el nombre completo de la clase derivada. Cualquiera de estos es equivalente a lo que ya estás haciendo; No hay una mejor solución que yo sepa. La naturaleza misma de los métodos estáticos excluye cualquier cosa más elegante.

No estoy seguro de cuáles son tus objetivos de diseño, pero por lo que preguntaste, parece que podría terminar con mucho olor a código. Creo que realmente debería examinar los patrones de diseño de Inversion of Control (IoC) / Dependency Injection (DI) que se implementan en numerosos marcos, como Microsoft Unity, Castle Windsor, StructureMap, Ninject, Spring.Net, etc.

Creo que si observa el uso de un contenedor IoC, resolverá su problema de una manera mucho más limpia y poco acoplada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top