2

I have bullets:

public LaserBullets : Projectile

I have a gun that inherits from a base weapon with the bullet type that goes with the derived gun:

public LaserWeapon : Weapon<LaserBullets>

I have a property to establish the current weapon of a player:

public Weapon<Projectile> CurrentWeapon
{
    set { currentWeapon = value; }
}

This fails (cannot implicitly cast LaserWeapon to Weapon<Projectile>)

player.CurrentWeapon = new LaserWeapon();

I've read about no support for certain covariance in C#, but I don't want to think that I'm stuck here. Is there any way to make my situation work? I'm trying to maintain a base weapon in the player class but work with a more specific weapon in another class.

I tried creating my own cast operator for LaserWeapon but I got an error about being unable to cast to/from base class.

4

2 回答 2

5

Weapon<T>我相信如果是这样声明的协变接口,您的示例会起作用:

public interface Weapon<out TProjectile>
{
}

这仅适用于TProjectile用作返回值的地方,例如:

TProjectile Fire();

但在用作输入参数的地方不起作用,例如: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()which 将返回Projectile.

于 2012-07-22T23:00:55.833 回答
1

Weapon创建一个继承的非泛型类Weapon<T>。使用该类而不是Weapon<Projectile>在您的代码中。

于 2012-07-22T23:06:54.177 回答