C#继承包含另一个可继承的对象?

时间:2015-11-14 17:50:00

标签: c# inheritance

我有以下对象

class Magazine 
{ 
    String intendedGunId {get;}//Returns some Gun.weaponID;
    int size {get;}
    //Implementation
}

class Gun 
{
    public enum FireModes
    {
        Bolt,
        Semi,
        FullAuto
    }

    public FireModes fireMode { get; private set; }

    Magazine magazine;

    public Magazine reload(Magazine newMag)
    {
        if (magazine.intendedGunId == newMag.intendedGunID)
        {
            Magazine temp = magazine;
            this.magazine = newMag;
            return temp;
        }

         return newMag;
    }

    //Other implementation
 }

class AKMag : Mag
{
   //Implementation
}

class AK : Gun
{
   //Implementation
}

我正在设计一把枪和一本杂志,应该总是在所说的枪中使用多种不同的枪。

我不认为将杂志变量保持为T : Magazine而不仅仅是杂志是一个明智的想法,因为重新加载时,几乎任何杂志都可以被接受,而且它并不安全码;我觉得黑客很容易利用这一点。

我尝试了以下通用:

class Gun<T> where T : Magazine
{
    T magazine;
    //Other implementation
}

class AK : Gun<AKMag>
{

}

问题是,一旦我使用泛型,就不可能存储Gun<Magazine>变量,因为在某些时候,编译器会说&#34;无法从Gun<AKMag>转换为{{1 }}

基本上,每支枪都有自己的mag,只属于它的枪。我正在努力正确地实现这一点,可能是因为缺乏对C#泛型或C#继承的理解。

编辑: 使用枪通用,以下方案不起作用:

Gun<T> where T : Magazine

编辑:我认为最好的方法是每当磁盘发生变化时检查magazine.GetType()== newMag.GetType(),但接口也可以正常工作。

2 个答案:

答案 0 :(得分:1)

如何使用普通的旧界面?

    class Program
    {
        static void Main(string[] args)
        {
            Gun myGun = new AK();
            Console.WriteLine(myGun.load(new AK_Mag())); // true
            Console.WriteLine(myGun.load(new ShotGun_Mag())); // false
            func2();
        }

        static Gun someGun;
        static void func1(Gun gun)
        {
            someGun = gun; 
        }

        public static void func2()
        {
            Gun someAK = new AK();
            someAK.load(new AK_Mag());
            func1(someAK);
        }
    }

    public class AK : Gun
    {
        public bool load(Mag mag)
        {
            if (mag == null)
                return false;
            if ( mag.GetType() != typeof(AK_Mag))
            {
                return false;
            }

            return true;
        }

        public void shoot(int x, int y, int z)
        {
            throw new NotImplementedException();
        }

        public bool setFireMode(Gun.FireMode mode)
        {
            this.mode = mode;
            return true;
        }
    }

    public class AK_Mag : Mag
    {
        public int Remain()
        {
            throw new NotImplementedException();
        }
    }

    public class ShotGun_Mag : Mag
    {
        public int Remain()
        {
            throw new NotImplementedException();
        }
    }

    public interface Gun
    {
        public enum FireMode { Manual, Burst };
        bool load(Mag mag);
        void shoot(int x, int y, int z);
        bool setFireMode(FireMode mode);        
    }

    public interface Mag
    {
        int Remain();
    }

答案 1 :(得分:1)

泛型类型参数的继承不涉及泛型类的继承。我认为泛型不是正确的解决方案。

尝试这种方法:

class Magazine
{
    public readonly Type GunType; // Used for identification of compatible gun type.

    public Magazine (Type gunType)
    {
        this.GunType = gunType;
    }
}

class Gun
{
    // Factory method
    public Magazine CreateMagazine()
    {
        return new Magazine(this.GetType());
    }

    public Magazine Reload(Magazine newMag)
    {
        // Test whether the magazine is compatible with the current gun.
        if (newMag.GunType != this.GetType()) {
            throw new ArgumentException();
            // Or just reject the new magazine and keep the current one.
        }

        // Your reload logic goes here ...
    }
}

泛型的问题在于T<A>T<B>两种类型不兼容,即使AB之间存在继承关系。另一个问题是,泛型在编译时完全解决了。你需要一个更加动态的方法。在游戏中,您可能希望将枪支和杂志存储在用户的库存中,并以相同的方式处理所有枪支和杂志类型。将所需类型存储为System.Type可以在运行时以完全动态的方式完成。

您可以创建和使用这样的杂志:

Gun gun = new AK();
Magazine magazine = gun.CreateMagazine();
Magazine other = gun.Reload(magazine);