2010-08-04 14 views
10

Tengo una colección de objetos que paso como parámetro para crear objetos de otro tipo (uno por uno). Estoy haciendo esto en muchos lugares (básicamente convirtiendo objetos de datos en objetos comerciales). Quiero escribir un método de extensión genérico para lograr esto. Pero estoy atascado porque no sé cómo puedo especificar la restricción de que el objeto comercial tiene un constructor que toma un objeto de datos como parámetro. El siguiente es el código de mi función:Especificación de la restricción del constructor para el parámetro genérico

public static IList<T> ConvertTo<A,T>(this IEnumerable<A> list) 
        where T : new(A)/*THIS IS PROBLEM PART*/ 
{ 
    var ret = new List<T>(); 

    foreach (var item in list) 
    { 
     ret.Add(new T(item)); 
    } 
    return ret; 
} 

Respuesta

13

Lamentablemente, esto no está permitido en C#. Puede tener una restricción new() que obligue al tipo a tener un constructor predeterminado, pero esa es la única restricción relacionada con el constructor compatible con .NET.

Su mejor opción es probablemente definir una interfaz que pueda usar y restringir a la interfaz. En lugar de tratar de establecer el objeto en construcción, puede tener un método de estilo "Inicializar" que toma el objeto "A" y llamarlo.

+0

Sí, la forma de interfaz es buena y puedo usarla porque estoy usando la plantilla T4 para generar BO, por lo que no será demasiado trabajo. – TheVillageIdiot

3

No se puede restringir constructores de tipos genéricos de esta manera (sólo requieren un constructor sin parámetros), pero se puede tomar un delegado para hacer la construcción:

public static IList<T> ConvertTo<A, T>(this IEnumerable<A> list, Func<A, T> constructionFunc) 
{ 
    return list.Select(constructionFunc).ToList(); 
} 

Y utilizar de esta manera:

var IList<T> converted = someSequence.ConvertTo(a => new T(a)); 
+0

¿algún ejemplo de parámetro de función? ¿Dónde debería definirlo en la clase T? – TheVillageIdiot

Cuestiones relacionadas