我有以下对象
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(),但接口也可以正常工作。
答案 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>
两种类型不兼容,即使A
和B
之间存在继承关系。另一个问题是,泛型在编译时完全解决了。你需要一个更加动态的方法。在游戏中,您可能希望将枪支和杂志存储在用户的库存中,并以相同的方式处理所有枪支和杂志类型。将所需类型存储为System.Type
可以在运行时以完全动态的方式完成。
您可以创建和使用这样的杂志:
Gun gun = new AK();
Magazine magazine = gun.CreateMagazine();
Magazine other = gun.Reload(magazine);