C# 基类为的调用泛型无法从基类转换为T
我有以下设置,似乎我的对象无法转换为泛型类型。而它实际上是基类。为什么这样不行?在我看来,这是合乎逻辑的C# 基类为的调用泛型无法从基类转换为T,c#,generics,C#,Generics,我有以下设置,似乎我的对象无法转换为泛型类型。而它实际上是基类。为什么这样不行?在我看来,这是合乎逻辑的 public class AList<T> where T : A { void DoStuff(T foo) { } void CallDoStuff() { DoStuff(new A()); // ERROR: Cannot convert A to T } } public class A { } 公共
public class AList<T> where T : A
{
void DoStuff(T foo)
{
}
void CallDoStuff()
{
DoStuff(new A()); // ERROR: Cannot convert A to T
}
}
public class A
{
}
公共类列表,其中T:A
{
空位(T-foo)
{
}
void CallDoStuff()
{
DoStuff(新A());//错误:无法将A转换为T
}
}
公共A类
{
}
这与对象不能隐式转换为int
的原因相同
该方法需要一个子类,而您正在传递父类,因此您需要显式强制转换。T
也可以是从a
派生的类,因此您不能将a
的实例作为T
类型的参数。类似于调用方法,它使用int
和类型为object
的参数,因为您要求T扩展A。因此可以用A替换T,但不能用T替换A
如果Cat:Animal,这并不意味着你总是可以将动物转换成Cat。这里的问题是约束条件说t
必须是a
或从a
派生的类
现在,当您用具体类型实例化AList
时,T
是一个非常特定的类。如果你没有用A
本身实例化AList
,而是用它的子类实例化,t
是A
的子类
不能将运行时类型为基类的实例转换为其子类之一,因为它会丢失子类添加的所有信息
例如:
public class Animal
{
public int Foo { get; set; }
}
public class Cat : Animal
{
public int Bar { get; set; }
}
Derived d = new Base();
您希望该代码正常工作吗?当然不是,因为猫也是动物,但是动物不是猫
如果您希望上面的代码能够实际工作,那么问问自己当执行以下代码时应该发生什么:d.Bar=42代码>
Animal
不包含Bar
的定义
同样的情况也发生在你的代码中——游戏中的泛型稍微模糊了一点。尝试使用Activator
从T
给你一个a
的实例,因为你知道T
必须是a
,因为受你的限制,所以不需要使用新的a()
只要您有T
,就可以在任何地方创建T
的实例
T obj = Activator.CreateInstance<T>();
DoStuff(obj);
很好的逻辑,我会这样说,“如果猫:动物,它并不意味着任何动物都是猫”。好吧,这是有道理的。我只是忘记了,这种显式的键入要求我确保这里的所有对象都可以是of,而不是。所以,如果我想这样做,也许我不应该首先使用泛型。@Marnix:正确。如果您不想强制执行a
的某个子类,但想同时允许所有子类和a
本身:不要使用泛型。My+1因为有时,在我们可爱的C#语言中会出现一些错误,甚至会让我们看到新的(以及更进一步的)维度。
T obj = (T)new A();
DoStuff(obj);