我有两类具有泛型的树,我一无所知,我知道如何用<? extends ...>
在Java中解决。
第一棵AI树:
abstract class AbstractAI<TCtrl> : MonoBehaviour where TCtrl: IRotableWeaponController
abstract class AbstractShipAI : AbstractAI<IShipController>
class ModularAI : AbstractShipAI
Some other classes that extend AbstractAI and use various modules
模块树:
abstract class AbstractModule<TAi, TCtrl> : AIModule where TAi: AbstractAI<TCtrl> where TCtrl: IRotableWeaponController
{
public virtual void Init(TAi parent)
}
class ShootModule: AbstractModule<AbstractAI<IRotableWeaponController>, IRotableWeaponController>
Some other modules that extend AbstractModule and can be used only with some AIs, that have required capabilities
使用的控制器接口树:
interface IRotableWeaponController
interface IShipController: IRotableWeaponController
Other interfaces extending IRotableWeaponController...
问题是:
class ModularAI : AbstractShipAI
{
public ShootModule shootModule;
protected override void Start()
{
shootModule.Init(this); // Error: Argument type 'ModularAI' is not assignable to parameter type 'AbstractAI<IRotableWeaponController>'
}
}
[ModularAI
是AbstractAI<IShipController>
,IShipController
是IRotableWeaponController
,但出现错误。
在Java中,我会这样做:
abstract class AbstractModule<TAi, TCtrl> : AIModule where TAi: AbstractAI<? extends TCtrl> where TCtrl: IRotableWeaponController
我知道它有点复杂,可能有一种更好的方法来设计它(而且我可能最终有一天会付诸实践),但是我想知道如何解决这个问题。拜托,我该怎么做?
class Fruit { }
class Apple : Fruit { }
class FruitMaker<T> where T : Fruit { }
class Program
{
static void HandleFruit(FruitMaker<Fruit> fruitMaker) { }
static void Main()
{
FruitMaker<Apple> appelMaker = new FruitMaker<Apple>();
FruitMaker<Fruit> fruitMaker = appelMaker; //cannot convert from 'FruitMaker<Apple>' to 'FruitMaker<Fruit>'
HandleFruit(fruitMaker);
}
}
您需要的是泛型协方差,您需要将FruitMaker<Apple>
传递给期望FruitMaker<Fruit>
的方法。这可以通过out
关键字启用,您想要的是class FruitMaker<out T> where T : Fruit { }
,但是您不能这样做,因为FruitMaker
不是接口。您可以按以下方式解决此问题:
class Fruit { }
class Apple : Fruit { }
interface IFruitMaker<out T> where T : Fruit { }
class FruitMaker<T> : IFruitMaker<T> where T : Fruit { }
class Program
{
static void HandleFruit(IFruitMaker<Fruit> fruitMaker) { }
static void Main()
{
FruitMaker<Apple> appelMaker = new FruitMaker<Apple>();
IFruitMaker<Fruit> fruitMaker = appelMaker; //this is allowed thanks to the out keyword
HandleFruit(fruitMaker);
}
}
注意,我引入一个界面只是为了添加out
键盘。
interface IAbstractAI<out TCtrl> where TCtrl : IRotableWeaponController {
}
abstract class AbstractAI<TCtrl> : MonoBehaviour, IAbstractAI<TCtrl> where TCtrl : IRotableWeaponController {
}
abstract class AbstractModule<TAi, TCtrl> : AIModule where TAi : IAbstractAI<TCtrl> where TCtrl : IRotableWeaponController {
public virtual void Init(TAi parent) {
}
}
class ShootModule : AbstractModule<IAbstractAI<IRotableWeaponController>, IRotableWeaponController> {
}
class ModularAI : AbstractShipAI {
public ShootModule shootModule;
protected override void Start() {
shootModule.Init(this); // Error: Argument type 'ModularAI' is not assignable to parameter type 'AbstractAI<IRotableWeaponController>'
}
}