我有一个不太优雅的解决方案,但我正在寻找一个优雅的解决方案来取代它。
以下代码无法编译,但代表了我想要做的事情:
interface IWebService
{
}
abstract class BaseClient<T>
{
}
class SpecializedClient : BaseClient<IWebService>
{
}
class ClientHelper<T> where T : BaseClient<*>
{
}
T
中的ClientHelper<T>
是任何扩展BaseClient
的类,无论传入的模板类型如何。
我找到的不优雅的解决方案是:
class ClientHelper<T, U> where T : BaseClient<U> {}
这变得不优雅的原因是我的项目最终得到了类似于:
的类class MyClass<A, B, C, D, E, F, G> where A : MyBaseClass<B, C, D, E, F, G>
一直到采用单一类型的基类。这只是具有泛型类的复杂继承树的成本,还是有一种更简单的方法来保留对模板化类型的类型限制?
答案 0 :(得分:5)
如果BaseClient的公共接口以任何方式公开它的泛型类型参数,那么你的“不优雅”解决方案是正确的。
所以假设BaseClient
不是,因为你定义了它:
abstract class BaseClient<T>
{
//Something about T here
}
然后T是BaseClient
的公共接口契约的一部分,因此是ClientHelper
的公共接口契约的一部分(再次假设BaseClient<U>
通过ClientHelper的接口公开)。
另一方面,让我们假设它实际上就像你的例子所说的那样:
abstract class BaseClient<T>
{
//Nothing about T here
}
在这种情况下,你可以这样做:
interface IBaseClient
{
//Nothing about T here
}
abstract class BaseClient<T> : IBaseClient
{
// Whatever you like here
}
和ClientHelper
变为:
class ClientHelper<T> where T : IBaseClient
{
}
答案 1 :(得分:0)
一个选项似乎是:
interface IWebService
{
}
interface IClient<out T>
{
}
abstract class BaseClient<T> : IClient<T>
{
}
class SpecializedClient : BaseClient<IWebService>
{
}
class ClientHelper<T> where T : IClient<object>
{
}
但是,只有当BaseClient
仅返回T
并且从不接受它时,这才有效。