[英]instantiate generic type in generic method
I have such a structure 我有这样的结构
void Main()
{
var lol = ActionClass.GetTestTuple<Request, Response, RequestCallInfo>("lol", "user");
lol.Dump();
}
public class ActionClass
{
public static Tuple<TRes, TInfo> GetTestTuple<TReq, TRes, TInfo>(string resultMsg, string userName)
where TReq : BaseRequest, new()
where TRes : BaseResponse, new()
where TInfo : CallInfo<TReq>, new()
{
var response = new TRes { Message = resultMsg };
var eventsInfo = new TInfo();
eventsInfo.Data.UserName = userName;
return new Tuple<TRes, TInfo>(response, eventsInfo);
}
}
public class Request : BaseRequest
{
}
public class Response : BaseResponse
{
}
public class RequestCallInfo : CallInfo<Request>
{
public string Item { get; set; }
}
public class CallInfo<GenericType> : BaseCallInfo where GenericType : BaseRequest, new()
{
public GenericType Data { get; set; }
public CallInfo(GenericType x)
{
Data = x;
}
}
public class BaseCallInfo
{
public string CallItem { get; set; }
}
public class BaseRequest
{
public string UserName { get; set; }
}
public class BaseResponse
{
public string Message { get; set; }
}
and when I execute it, I get UserQuery.CallInfo<UserQuery.Request> does not contain a constructor that takes 0 arguments,
当我执行它时,我得到
UserQuery.CallInfo<UserQuery.Request> does not contain a constructor that takes 0 arguments,
So i tried this way 所以我试过这种方式
public static Tuple<TRes, TInfo> GetTestTuple<TReq, TRes, TInfo>(string resultMsg, string userName)
where TReq : BaseRequest, new()
where TRes : BaseResponse, new()
where TInfo : CallInfo<TReq>, new()
{
var response = new TRes { Message = resultMsg };
var eventsInfo = new TInfo(new TReq { UserName = userName });
eventsInfo.Data.UserName = userName;
return new Tuple<TRes, TInfo>(response, eventsInfo);
}
but i'm getting 'TInfo': impossible to provide arguments when instantiating a type
但我得到
'TInfo': impossible to provide arguments when instantiating a type
How can I pass an instance of TReq
to TInfo
and keep only the parameter constructor in CallInfo<GenericType>
? 如何将
TInfo
实例TReq
给TInfo
并仅在CallInfo<GenericType>
保留参数构造函数?
The new()
constraint only requires that a generic type have a public parameter-less constructor; new()
约束只要求泛型类型具有公共参数构造函数; there is no way to specify specific construct signatures on a generic type / constraint in C#. 无法在C#中的泛型类型/约束上指定特定的构造签名。 Given that, the compiler cannot know what constructors would be available by callers, so you can't instantiate a generic type using constructor parameters.
鉴于此,编译器无法知道调用者可以使用哪些构造函数,因此您无法使用构造函数参数实例化泛型类型。
So you could use reflection here if you would like, but this solution seems simpler based on the code you've provided: 因此,如果您愿意,可以在此处使用反射,但根据您提供的代码,此解决方案似乎更简单:
var eventsInfo = new TInfo() { Data = new TReq { UserName = userName } };
You should use Activator.CreateInstance
method. 您应该使用
Activator.CreateInstance
方法。
Working solution: 工作方案:
public class ActionClass
{
public static Tuple<TRes, TInfo> GetTestTuple<TReq, TRes, TInfo>(string resultMsg, string userName)
where TReq : BaseRequest, new()
where TRes : BaseResponse, new()
where TInfo : CallInfo<TReq>
{
var response = new TRes { Message = resultMsg };
var eventsInfo = (TInfo)Activator.CreateInstance(typeof(TInfo), new []{ new TReq() });
eventsInfo.Data.UserName = userName;
return new Tuple<TRes, TInfo>(response, eventsInfo);
}
}
public class BaseCallInfo
{
public string CallItem { get; set; }
}
public class BaseRequest
{
public string UserName { get; set; }
}
public class BaseResponse
{
public string Message { get; set; }
}
public class Request : BaseRequest
{
}
public class Response : BaseResponse
{
}
public class RequestCallInfo : CallInfo<Request>
{
public string Item { get; set; }
public RequestCallInfo(Request x) : base(x)
{
}
}
public class CallInfo<GenericType> : BaseCallInfo where GenericType : BaseRequest, new()
{
public GenericType Data { get; set; }
public CallInfo(GenericType x)
{
Data = x;
}
}
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.