我创建了这样的类:
abstract class AClass1<T>
{
// some code here
}
class Class2 : AClass1<int>
{
// some code here
}
class Class3 : AClass1<float>
{
// some code here
}
class Class4<T> : AClass1<T>
{
// some code here
}
到目前为止它的确有效。但在另一个课程中,我希望:
...
AClass1<T> variable;
并根据具体需要将变量设置为:
variable = new Class2();
或
variable = new Class3();
或有时:
variable = new Class4<T>();
这会产生编译错误,没有可能的强制转换或我尝试过的任何其他内容。目前我只是将所有继承类更改为泛型,如:
class Class2<T> : AClass1<T>
{
// some code here
}
但感觉不对,因为那里没有通用的方法或任何东西。
问题是什么是正确的方法,为什么,为什么我不能用我原来的方式做到这一点?
顺便说一下,这是.net 2.0,因为我在Unity3D中这样做。
更清楚:
我有一些特殊情况,例如对于我想要专门处理的int类型,但还有其他我希望有一个泛型类。所以我创建了一些特定处理某些类型的子类,并且我还有一个通用子类,当没有特定的类型实现时我会使用它。当我为一个类型创建一个特定的类时,它不应该是通用的,因为它只处理一种类型。
答案 0 :(得分:1)
Class2
对象无法分配给AClass1<T>
变量,因为Class2
不是来自AClass1<T>
,而是来自AClass1<int>
。这些是不兼容的类型,编译器无法在它们之间进行转换。因此编译错误。
也许您可以为AClass1<T>
引入非通用基类?
答案 1 :(得分:1)
编译器正在尝试通过确保您不执行无法保证工作的分配来帮助您。这不合法:
void foo<T>() {
...
if (typeof(T) == typeof(int)) {
AClass1<T> variable = new Class2();
}
...
}
那是因为Class2
只与AClass1<int>
兼容 - 如果我们不知道T
是什么,我们通常不能说它与AClass1<T>
兼容。在上面的代码中,确定转换是可能的,但是编译器不够复杂,无法确定此代码是否安全 - 通常,如果没有if
,它就不会#39}是的。投射也不起作用,因为任意Class2
都没有从AClass1<T>
转换为T
。
为了完成这项工作,你必须放弃编译时类型检查并强制进行运行时转换 - 在编译时转换成Object
总是合法的:
AClass1<T> variable = (AClass1<T>) (object) new Class2();
如果你弄错了,代码将在运行时失败InvalidCastException
。
这种方法很可疑,因为它提出了为什么使用泛型(编译时类型特性)然后在实际代码中绕过它们的问题。像这样的代码必须仔细审查,看看这是否真的是最合适的解决方案。可能的替代方法是引入非泛型基类,使用包含泛型类型,或者根本不使用泛型(如果您真的只使用float
和int
,则是通用基类添加什么?)