【发布时间】:2022-10-24 21:13:31
【问题描述】:
我有很多函数都接受一个类(请求)并返回一个类(响应),我正在尝试编写一个通用处理程序。
我无法更改我的类JobParametersModel 的定义以接受泛型或我的方法DoWorkAsync,但我可以修改其他所有内容。
鉴于这些类:
public class JobRequestModel<Request, Response>
where Request : class
where Response : class
{
public Func<Request, Task<Response>> CallDelegate { get; set; }
public async Task<Response> DoCall(Request request)
{
return await CallDelegate(request);
}
}
public sealed class JobParametersModel
{
// Stores class JobRequestModel and other params
public object RequestModel { get; set; }
}
这是我试图解决的方法。我怎样才能让对象变成我可以与之交互的东西?
// What I'm trying to do, that does not work.
public async Task<JobResultModel> DoWorkAsync(JobParametersModel work, object request)
{
var jobRequestModel = (JobRequestModel)work.RequestModel; // Does NOT work.
// I can cast request using "ChangeType". Simplified code for example
var results = await jobRequestModel.DoCall(request);
// I package/return results later
}
这样我就可以这样称呼它:
var result1 = await DoWorkAsync(
new JobParametersModel()
{
RequestModel = new JobAXRequestModel<CustomRequestType, CustomResponseType>()
{
CallDelegate = _client.getMyCustomDelegate
}
},
new CustomRequestType()
{
CustomField1 = "something",
CustomField2 = 4
}
);
var result2 = await DoWorkAsync(
new JobParametersModel()
{
RequestModel = new JobAXRequestModel<OtherCustomRequestType, OtherCustomResponseType>()
{
CallDelegate = _client.getSomeOtherCustomDelegate
}
},
new OtherCustomRequestType()
{
DifferentField1 = "other things"
}
);
【问题讨论】:
-
既然你必须写
RequestModel = new JobAXRequestModel<CustomRequestType, CustomResponseType>(),你能不能简单地写public async Task<JobResultModel> DoWorkAsync<Request, Response>(JobParametersModel work, object request) where Request : class where Response : class和var jobRequestModel = (JobRequestModel<Request, Response>)work.RequestModel;? -
代码被简化了,但它实际上是更大的队列/轮询框架的一部分。我不直接调用该方法,因此很遗憾,如果不重写整个框架,我就无法修改该函数定义。
-
这与我无法更改我的类
JobParametersModel的定义以接受泛型,但我可以修改其他所有内容:) -
也许您可以扔几只鸭子并将
var jobRequestModel = (JobRequestModel)work.RequestModel替换为dynamic jobRequestModel = work.RequestModel- 一旦它变成动态的,那么只要签名匹配,您就应该能够调用DoCall方法。 -
@MetroSmurf 看起来我能够让它工作!这是访问泛型的最佳方式还是应该添加更多反射检查?
标签: c# asp.net generics async-await casting