将非通用类转换为通用基类

时间:2020-06-04 21:53:03

标签: c# unity3d generics

我想将非通用类放入具有通用基类类型的List中。但是,该代码不会与无法进行转换的错误一起编译。我是C#的新手,所以我可能会在这里错过一些非常基本的东西,或者我不想使用泛型,这不是一个好主意吗?我的代码看起来像这样:

public abstract class AbstractClass{
  public string foo;
}

public class A : AbstractClass{
  public int bar
}

public class B : AbstractClass{
  public int baz
}

public abstract class AbstractBehaviour<T> : MonoBehaviour where T : AbstractClass{
  public T data;
  public abstract string compute(T arg);
}

public class ABehaviour : AbstractBehaviour<A>{
  //some implementation of compute
}

public class BBehaviour : AbstractBehaviour<B>{
  //some implementation of compute
}

通过此设置,我想执行以下操作:

ABehaviour a = new ABehaviour();
BBehaviour b = new BBehaviour();
List<AbstractBehaviour<AbstractClass>> list = new List<AbstractBehaviour<AbstractClass>>();
list.Add(a);
list.Add(b);

非常感谢您。

2 个答案:

答案 0 :(得分:1)

通话时:

List<AbstractBehaviour<AbstractClass>> list = new List<AbstractBehaviour<AbstractClass>>();

请注意,您的类AbstractBehaviour需要T必须是AbstractClass,而不是类型本身。

因此您可以这样做:

List<AbstractBehaviour<A>> list = new List<AbstractBehaviour<A>>();

原因A实现的是AbstractClass类型,而不是类型本身。

编辑:要在列表中存储这两个AbstractBehaviour,您需要找到“最小公共类”(在本例中为Monobehaviour),因为AbstractBehaviour继承自Mono。

因此,如果您这样做:

List<MonoBehaviour> list = new List<MonoBehaviour>();
list.Add(a);
list.Add(b);

它将编译,但随后您必须检查集合中要处理的是哪种类型,并进行如下转换:

ABehaviour aBehaviour = (ABehaviour)list[0];
BBehaviour bBehaviour = list[1] as BBehaviour;

答案 1 :(得分:1)

您不能这样做,因为AbstractBehaviour<A>(或AbstractBehaviour<B>)不是AbstractBehaviour<AbstractClass>。如果我们以Compute方法为例-用AbstractBehaviour<AbstractClass>类型的参数调用AbstractClass绝对有效,而用此参数调用AbstractBehaviour<A>.compute绝对无效。

还请阅读有关covariance and contravariance in C#的信息(但这对您的Compute方法没有帮助)

相关问题