我正在尝试编译以下代码:
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
会容易得多,但是它把确定具体返回类型的负担交给了调用者,而不是请求处理程序(它当然知道所有关于输入的信息)。
最佳答案
正如我在评论中所说,我怀疑你做错了。这看起来像是对泛型的滥用。
也就是说,您告诉编译器“我知道的类型信息比您多”的方式是通过强制转换。
var response = new FooResponse(...);
return (TResponse)(object)response;
转换为对象然后转换为 TResponse 告诉编译器“我知道从响应到 TResponse 有身份、拆箱或引用转换”。如果你错了,你会在运行时得到一个异常。
关于c# - 将具体类型转换为泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9420037/