¿Existe una manera elegante de crear instancias de un tipo de variable con parámetros?

Esto no es legal

public class MyBaseClass
{
  public MyBaseClass() {}
  public MyBaseClass(object arg) {}
}


public void ThisIsANoNo() where T : MyBaseClass
{
  T foo = new T("whoops!");
}

Para hacer esto, debe hacer una reflexión sobre el tipo de objeto para T o tiene que usar Activator.CreateInstance. Ambos son bastante desagradables. ¿Hay una mejor manera?

0
agregado
Puntos de vista: 1

4 Respuestas

where T : MyBaseClass, new()

solo funciona con el constructor público sin parámetros. más allá de eso, de vuelta a activador.CreateInstance (que realmente no es tan malo).

0
agregado
no de una manera genérica
agregado el autor Darren Kopp, fuente

Puedo ver que no funciona.

Pero, ¿qué es lo que te impide hacer esto?

public void ThisIsANoNo() where T : MyBaseClass
{
  MyBaseClass foo = new MyBaseClass("whoops!");
}

Como todo va a heredar de MyBaseClass, todos serán MyBaseClass, ¿verdad?

Lo intenté y esto funciona.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ThisIsANoNo();
            ThisIsANoNo();
        }

        public class MyBaseClass
        {
            public MyBaseClass() { }
            public MyBaseClass(object arg) { }
        }

        public class MyClass :MyBaseClass
        {
            public MyClass() { }
            public MyClass(object arg, Object arg2) { }
        }

        public static void ThisIsANoNo() where T : MyBaseClass
        {
            MyBaseClass foo = new MyBaseClass("whoops!");
        }
    }
}
0
agregado
T es una extensión de MyBaseClass. Puede actualizar una instancia de MyBaseClass, pero no puede "actualizarla" a T, porque no es una T. Además, su implementación ThisIsANoNo, si bien tiene una firma genérica, no actualiza una instancia de la tipo variable
agregado el autor Will, fuente
es un vacío que no devuelve nada. y un elenco puede arreglar eso.
agregado el autor chrissie1, fuente
@A lo probé y funciona.
agregado el autor chrissie1, fuente
¿Qué sucede si tienes una clase derivada que solo tiene un constructor que toma 2 argumentos?
agregado el autor Abe Heidebrecht, fuente
Este método nunca devolverá objetos de tipo T, solo objetos de tipo MyBaseClass.
agregado el autor Matt Howells, fuente

Nop. Si no estaba pasando parámetros, entonces podría restringir su tipo param para requerir un constructor sin parámetros. Pero, si necesita pasar argumentos, no tiene suerte.

0
agregado

No puede obligar a T a tener una firma de constructor particular que no sea un constructor vacío, pero puede restringir a T para que tenga un método de fábrica con la firma deseada:

public abstract class MyBaseClass
{
    protected MyBaseClass() {}
    protected abstract MyBaseClass CreateFromObject(object arg);
}

public void ThisWorksButIsntGreat() where T : MyBaseClass, new()
{
    T foo = new T().CreateFromObject("whoopee!") as T;
}

Sin embargo, sugeriría quizás usar un patrón de creación diferente, como Abstract Factory para este escenario.

0
agregado