我有子弹:
public LaserBullets : Projectile
我有一把枪,它继承了一种基本武器,其子弹类型与衍生枪一起使用:
public LaserWeapon : Weapon<LaserBullets>
我有一个属性来建立玩家的当前武器:
public Weapon<Projectile> CurrentWeapon
{
set { currentWeapon = value; }
}
此操作失败(无法隐式投射LaserWeapon
至Weapon<Projectile>
)
player.CurrentWeapon = new LaserWeapon();
我读过关于C#中某些协方差的支持,但我不想认为我被困在这里。有没有办法让我的情况有效?我正在尝试在玩家类中维护一个基础武器,但是在另一个类中使用更具体的武器。
我尝试为LaserWeapon创建自己的强制转换操作符,但是我收到了一个关于无法强制转换为基类的错误。
答案 0 :(得分:5)
我相信如果Weapon<T>
是一个如此声明的协变接口,那么你的例子就会有效:
public interface Weapon<out TProjectile>
{
}
这仅适用于将TProjectile
用作返回值的情况,例如:
TProjectile Fire();
但 NOT 会将TProjectile
用作输入参数,例如:
LoadClip(IEnumerable<TProjectile> ammo);
从您的评论中,我可以看到您在通用返回值之后,因此请按如下方式创建一个界面:
public interface IWeapon<out TProjectile> where TProjectile : Projectile
{
TProjectile Fire();
}
然后使用此接口实现;没有什么能阻止你拥有一个有用的基类,例如
public abstract class Weapon<TProjectile> : IWeapon<TProjectile> where TProjectile : Projectile
{
public abstract TProjectile Fire();
}
只要你的玩家类别符合以下几行:
public class Player
{
public IWeapon<Projectile> CurrentWeapon { get; set; }
}
这样,您仍然可以使用CurrentWeapon.Fire()
来返回Projectile
的实例。
答案 1 :(得分:1)
创建Weapon
继承的非泛型类Weapon<T>
。在代码中使用该类而不是Weapon<Projectile>
。