我正在尝试编译以下代码:
public class BaseRequest<TResponse> where TResponse : BaseResponse {}
public class BaseResponse {}
public class FooRequest : BaseRequest<FooResponse> {}
public class FooResponse : BaseResponse {}
...
public TResponse MakeRequest<TResponse>(BaseRequest<TResponse> request)
where TResponse : BaseResponse
{
}
Run Code Online (Sandbox Code Playgroud)
我希望我可以调用MakeRequest(new FooRequest())并获取返回值FooResponse.被调用者不必知道FooRequest并可能将其传递给另一个处理程序.签名工作正常,但我无法实现该MakeRequest方法.如果我实现它像:
public TResponse MakeRequest<TResponse>(BaseRequest<TResponse> request)
where TResponse : BaseResponse
{
FooRequest fooRequest = request as FooRequest;
if (fooRequest != null) // if I can handle the request, handle it
{
return new FooResponse(...); // ***
}
BarRequest barRequest = request as BarRequest;
if (barRequest != null)
{
return new BarResponse(...);
}
else // otherwise, pass it on to the next node
{
// maybe it will handle a BazRequest, who knows
return nextNode.MakeRequest(request);
}
}
Run Code Online (Sandbox Code Playgroud)
但该***行不会编译,因为编译器不知道FooResponse是一个TResponse.我知道这是因为它已经指定了FooRequest.有没有办法解决这个问题,而不涉及讨厌的反思(在这种情况下,我宁愿返回BaseResponse)?
谢谢.
更新:我正在使用泛型来强制执行返回类型,以便调用站点确切地知道预期的内容.回到BaseResponse这里要容易得多,但是它把具体的返回类型的负担放到了调用者而不是请求处理程序(当然知道关于打字的所有内容).
正如我在评论中所说,我怀疑你做错了.这看起来像滥用泛型.
也就是说,你告诉编译器"我知道比你更多的类型信息"的方式是通过强制转换.
var response = new FooResponse(...);
return (TResponse)(object)response;
Run Code Online (Sandbox Code Playgroud)
转换为对象然后转向TResponse告诉编译器"我知道从响应到TResponse有一个标识,拆箱或引用转换".如果你错了,你会在运行时得到一个例外.
| 归档时间: |
|
| 查看次数: |
2472 次 |
| 最近记录: |