2012-08-06 25 views
5

tengo el siguiente método de ayuda:Sin el boxeo o el tipo de conversión de parámetros para el parámetro genérico Tipo

public static T CreateRequest<T>() 
    where T : Request, new() 
{ 
    T request = new T(); 
    // ... 
    // Assign default values, etc. 
    // ... 
    return request; 
} 

Quiero usar este método desde el interior de otro método en el otro ayudante:

public T Map<F, T>(F value, T toValue) 
    where T : new() 
    where F : new() 
{ 
    if (typeof(T).BaseType.FullName == "MyNamespace.Request") 
    { 
     toValue = MyExtensions.CreateRequest<T>(); 
    } 
    else 
    { 
     toValue = new T(); 
    } 
} 

pero entonces me sale el error:

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'MyExtensions.CreateRequest()'. There is no boxing conversion or type parameter conversion from 'T' to 'MyNamespace.Request'.

¿hay una manera de convertir el tipo "T", de manera que woul createRequest d usarlo sin problemas?

EDIT:

Sé que puedo hacer dos cosas:

  • aflojar las restricciones sobre createRequest o
  • apriete contraints en Mapa.

Pero no puedo hacer la primera, porque en CreateRequest I las propiedades de usuario de la clase Request, y no puedo hacer la segunda, porque uso otros tipos (que no heredan de Request) con Map función.

+0

que significa: "uno o ninguno" –

Respuesta

4

Para este escenario que necesita para aflojar las restricciones genéricas de CreateRequest.

public static T CreateRequest<T>() 
    where T : new() 
{ 
    if(!typeof(Request).IsAssignableFrom(typeof(T))) 
     throw new ArgumentException(); 

    var result = new T(); 
    Request request = (Request)(object)result; 
    // ... 
    // Assign default values, etc. 
    // ... 
    return result ; 
} 

Puede ser doloroso porque se pierde la verificación de compilación de este parámetro.

O si desea utilizar el método CreateRequest en otro lugar, cree una sobrecarga no genérica solo para este escenario.

public static object CreateRequest(Type requestType) 
{ 
    if(!typeof(Request).IsAssignableFrom(requestType)) 
     throw new ArgumentException(); 

    var result = Activator.CreateInstance(requestType); 
    Request request = (Request)result; 
    // ... 
    // Assign default values, etc. 
    // ... 
    return result ; 
} 
+0

¿por qué es necesario este doble molde? '(Solicitud) (objeto) resultado;' –

+0

¡Buena captura con '.IsAssignableFrom'! mucho mejor que la comparación de cuerdas! –

+0

El reparto doble es para que el compilador le diga que usted sabe lo que hace y que se responsabiliza por ello. Sin él, no funcionará y el anterior asegura que esto funcionará. – Rafal

3

Ha declarado que el tipo de T es Request en CreateRequest method; por otro lado, en el método Map no tiene tal restricción. Prueba a cambiar la declaración de Map a:

public T Map<F, T>(F value, T toValue) 
where T : Request, new() 
where F : new() 
+0

El problema es que utilizo la función de mapa con los tipos, que no heredan desde la solicitud, por lo que no se puede establecer este contraint. –

+0

Luego puede intentar eliminar la restricción de solicitud de la función CreateRequest. – daryal

Cuestiones relacionadas