c# - 具有匹配泛型参数的泛型类不是有效的基类
问题描述
为什么在下面的示例中Base<BaseResult<bool, object>, bool, object>
不是有效的基类Concrete<object>
?Base<BaseResult<bool, object>, bool, object>
是 的基础SpecializedBase<bool, object>
,并且SpecializedBase<bool, object>
似乎是 的适当基础Concrete<object>
?
public abstract class Base<TResult, TOutcome, TOutput>
where TResult : BaseResult<TOutcome, TOutput>
where TOutput : class
{
}
public class BaseResult<TOutcome, TOutput>
{
}
public abstract class SpecializedBase<TResult, TOutput> :
Base<SpecializedResult<TOutput>, bool, TOutput>
where TOutput : class
{
}
public class SpecializedResult<TOutput> : BaseResult<bool, TOutput>
{
}
public class Concrete<TOutput> :
SpecializedBase<SpecializedResult<TOutput>, TOutput>
where TOutput : class
{
}
static class Program {
static void main()
{
// #1: works
SpecializedBase<SpecializedResult<object>, object> obj;
obj = new Concrete<object>();
// #2: works
Base<SpecializedResult<object>, bool, object> obj2;
obj2 = new Concrete<object>();
// #3: doesn't work:
// Cannot implicitly convert type 'TypeTest.Concrete<object>' to 'TypeTest.Base<TypeTest.BaseResult<bool, object>, bool, object>'
Base<BaseResult<bool, object>, bool, object> obj3;
obj3 = new Concrete<object>();
}
}
}
解决方案
让我们尝试逐步解析类型。
Concrete<object>
是 SpecializedBase<SpecializedResult<object>, object>
。
SpecializedBase<SpecializedResult<object>, object>
是 Base<SpecializedResult<object>, bool, object>
。
就是这样。Base
直接继承自Object
,因此最终派生最少的类型是Base<TResult, TOutcome, TOutput>
set TResult
to SpecializedResult<object>
、TOutcome
tobool
和TOutput
to object
。这种类型是不变的,因此Base<SpecializedResult<object>, bool, object>
不是 Base<BaseResult<bool, object>, bool, object>
。
您可以在 MSDN docs、this SO question和this SO question中找到更多关于通用差异的信息(可能还有其他一千个地方,这是一个众所周知的复杂概念)。
推荐阅读
- hadoop - Hadoop:hadoop namenode -format 会破坏数据节点,为什么?
- c++ - 有没有办法让 Visual Studio 编译器为此 C++ 代码发出警告?
- python - Python:在列表列表中查找名称
- python - Pandas 数据框 - 按来自另一个数据框的值过滤行
- numpy - 向量化正则化梯度下降未通过数值检查
- postgresql - 从第一个查询中创建的行获取串行 PK 以查询另一个表
- automation - 自动化 Fortify SSC 报告
- java - Java中枚举内的EnumSet修饰符
- github - CODEOWNERS 语法:/foobar/** vs /foobar/
- import - 如何导入整个three.js核心库?