我正在尝试编译以下代码:
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
{
}
我希望能够调用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);
}
}
但是,
***
行无法编译,因为编译器不知道FooResponse
是TResponse
。我知道这是因为它在FooRequest
中指定了。有没有任何方法可以避免涉及令人讨厌的反射而解决这个问题(如果要使用反射的话,我更愿意返回BaseResponse
)?谢谢。
更新:我使用泛型来强制返回类型,因此调用者知道应该期望什么。在这里只返回
BaseResponse
会容易得多,但这将把找出具体返回类型的负担转移到调用者身上,而不是请求处理程序(当然,请求处理程序对类型信息非常了解)。
if (request is FooRequest) { ... }
即可。 - Chris ShainFooResponse response = chain.MakeRequest(new FooRequest)
。换句话说,在消息处理程序中将BaseResponse
转换为FooResponse
,而不是在调用方处进行转换。 - Todd Li