Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No boxing or type parameter conversion for generic Type parameter

Tags:

c#

types

casting

I have the following helper method:

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

I want to use this method from the inside of another method in another helper:

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();
    }
}

But then I get the 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'.

Is there a way to cast the type "T", so that CreateRequest would use it without problems?

EDIT:

I know I can do two things:

  • loosen constraints on CreateRequest or
  • tighten contraints in Map.

But I can't do the first, because in CreateRequest I user properties of Request class, and I can't do the second, because I use other types (that don't inherit from Request) with Map function.

like image 951
Lukasz Lysik Avatar asked Aug 06 '12 06:08

Lukasz Lysik


1 Answers

For this scenario you'll need to loosen generic restrictions of 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 ;
}

It might be painful because you lose compile time verification of this parameter.

Or if you want to use CreateRequest method elsewhere then create non-generic overload for this scenario only.

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 ;
}
like image 67
Rafal Avatar answered Oct 19 '22 20:10

Rafal