2012-02-03 12 views
5
class MyClass<T> where T: new() 
{ 
    public Test() 
    { 
     var t = new T(); 
     var t = new T("blah"); // <- How to do this? 
    } 
} 

Sé que no es posible como está escrito, y por lo que yo entiendo simplemente no está permitido (aunque no me gustaría nada más que estar equivocado al respecto). La primera solución que se me viene a la mente es utilizar un inicializador de objetos, pero supongamos que es un último recurso porque entraría en conflicto con otros objetivos de OOP en este caso.Creando una instancia de un tipo genérico con un constructor sobrecargado

Mi próxima inclinación sería utilizar la reflexión, pero antes de hacerlo me gustaría saber si estoy pasando por alto alguna forma más sencilla de hacer esto o tal vez un patrón de diseño diferente que funcionaría mejor?

+1

Yo diría que la reflexión es su única esperanza. Pero con la reflexión, debe confiar en la convención en lugar de en la verificación del tiempo de compilación, que probablemente sea lo que está buscando. Tal vez podrías usar una fábrica quizás, pero no puedo ver cómo una fábrica podría ser genérica y aún así hacer el trabajo. Inicialización de objetos! = OOP. –

+0

Estoy de acuerdo con @ MikaelÖstberg y voy a utilizar una fábrica. – Lukazoid

+0

¿Pero podría la fábrica ser genérica? Me enfrentaría a los mismos desafíos que vemos en el código ahora. Las fábricas deberían ser concretas. –

Respuesta

4

No puede hacerlo directamente. Tendrá que utilizar Activator.CreateInstance, pero al hacerlo tiene todos los inconvenientes de reflexión, lo que significa que se pierda en el tiempo de compilación de cheques, etc.

public Test() 
{ 
    var t = (T)Activator.CreateInstance(typeof(T), (object)"blah"); 
} 
+0

Dulce, creo que esa es mi mejor opción. Lo he usado en el pasado y seguía pensando que podía hacer algo así en el fondo de mi mente, pero por alguna razón lo había olvidado y estaba pensando que la reflexión requeriría un código difícil de leer/mantener. . Esto es bastante simple sin embargo. –

3

Puede forzar el usuario para darle la forma de construir el objeto de string, así:

internal class MyClass<T> 
    where T : new() 
{ 
    public void Test(Func<string, T> func) 
    { 
     var t = func("blah"); 
    } 
} 

Function puede ser parte de contrucción MyClass objeto, por lo que no tendrá que pasar cada vez que se llama a métodos que tienen para crear T. De hecho, con ese enfoque new() podría no ser necesario.

+0

Hmm ... eso es interesante. Voy con la solución Activator.CreateInstance por ahora, pero si el rendimiento de la reflexión es menor que el deseado, tal vez me ocupe de probar esto. –

Cuestiones relacionadas