C# 通用类型参数没有装箱或类型参数转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11823608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:23:34  来源:igfitidea点击:

No boxing or type parameter conversion for generic Type parameter

c#typescasting

提问by Lukasz Lysik

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'.

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

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

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

EDIT:

编辑:

I know I can do two things:

我知道我可以做两件事:

  • loosen constraints on CreateRequest or
  • tighten contraints in Map.
  • 放松对 CreateRequest 的约束或
  • 收紧 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.

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

采纳答案by Rafal

For this scenario you'll need to loosen generic restrictions of CreateRequest.

对于这种情况,您需要放宽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 CreateRequestmethod elsewhere then create non-generic overload for this scenario only.

或者,如果您想在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 ;
}

回答by daryal

You have declared that the type of Tis Requestin CreateRequestmethod; on the otherhand, in Mapmethod you do not have such constraint. Try changing the declaration of Mapto:

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

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