简体   繁体   中英

Casting non generic class to generic base class

I want to put a non generic class into a List with the type of a generic base class. However the code wont combile with the error that a conversion is not possible. I am pretty new to C# so I might just miss something very basic here or my approch to use generics that way is just no good idea? My code looks something like this:

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
}

With this setup I would like to do something like this:

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

Thank you very much.

When you are calling:

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

Notice that your class AbstractBehaviour needs that T have to be an AbstractClass, not the type itself.

So you can do:

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

Cause A implements the type AbstractClass, it's not the type itself.

Edit : To store on the list both AbstractBehaviours you need to find the "minimum common class" which in this case is the Monobehaviour, cause AbstractBehaviour inherits from Mono.

So if you make:

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

It will compile, but then you have to check which type are you dealing inside the collections, doing casts like:

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

You can't because AbstractBehaviour<A> (or AbstractBehaviour<B> ) is not AbstractBehaviour<AbstractClass> . If we take for example Compute method - for AbstractBehaviour<AbstractClass> would be absolutely valid to call it with parameter of type AbstractClass while it is definitely not valid to call AbstractBehaviour<A>.compute with this parameter.

Also please read about covariance and contravariance in C# (but it will not help with your Compute method)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM