15

我有以下帮助方法:

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

我想在另一个助手的另一个方法内部使用这个方法:

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

但后来我得到了错误:

类型“T”不能用作泛型类型或方法“MyExtensions.CreateRequest()”中的类型参数“T”。没有从“T”到“MyNamespace.Request”的装箱转换或类型参数转换。

有没有办法转换类型“T”,以便 CreateRequest 可以毫无问题地使用它?

编辑:

我知道我可以做两件事:

  • 放松对 CreateRequest 的约束或
  • 收紧地图中的约束。

但我不能做第一个,因为在 CreateRequest 我使用 Request 类的属性,而我不能做第二个,因为我使用其他类型(不从 Request 继承)和 Map 函数。

4

2 回答 2

9

对于这种情况,您需要放宽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 ;
}

这可能会很痛苦,因为您失去了对该参数的编译时验证。

或者,如果您想在CreateRequest其他地方使用方法,则仅为这种情况创建非泛型重载。

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 ;
}
于 2012-08-06T06:55:27.217 回答
5

您已声明的类型T在方法RequestCreateRequest;另一方面,在Map方法中你没有这样的约束。尝试将声明更改Map为:

public T Map<F, T>(F value, T toValue)
where T : Request, new()
where F : new()
于 2012-08-06T06:48:28.870 回答