【发布时间】:2015-11-14 17:50:00
【问题描述】:
我有以下物品
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
}
我正在设计一把枪和一个弹匣,该枪应始终用于多种不同的枪。
我不认为将 Magazine 变量保留为 T : Magazine 而不仅仅是 Magazine 是一个聪明的主意,因为在重新加载时,几乎任何杂志都可以被接受,而且它感觉不像是安全代码;我觉得黑客很容易利用这一点。
我尝试了以下通用方法:
class Gun<T> where T : Magazine
{
T magazine;
//Other implementation
}
class AK : Gun<AKMag>
{
}
问题是一旦我使用泛型,就无法存储Gun<Magazine> 变量,因为在某些时候,编译器会说“无法从Gun<AKMag> 转换为Gun<T> where T : Magazine。
基本上,每把枪都有自己的弹匣,只属于它的枪。我正在努力正确地实现这一点,可能是因为对 C# 泛型或 C# 继承缺乏了解。
编辑: 使用枪通用,以下情况不起作用:
Gun<Magazine> someGun;
public void func (Gun<Magazine> gun)
{
this.someGun = gun;
}
//In another class
AK<AKMagazine> someAK;
public void func2 ()
{
func1 (someAK); //Error: "Can not convert from `Gun<AKMag>` to `Gun<T> where T : Magazine`."
}
编辑:我认为最好的方法是检查magazine.GetType() == newMag.GetType() 每当杂志要改变时,界面也可以工作。
【问题讨论】:
-
分享让编译器抱怨的代码。我不明白你的确切意思。
-
创建一个
IGun接口,在Gun<T>中实现它,并将你的枪存储在类型为IGun的变量中。 -
@MarcinJuraszek,我可以问你更多细节吗?我想我明白了,但我不确定我会怎么做。因为我不确定接口是否可以工作,所以我会向 Gun 类添加更多信息。
-
也许它有助于使
T协变 - 请参阅 stackoverflow.com/questions/10956993/out-t-vs-t-in-generics -
@Ruud,虽然这似乎可行,但它需要一个接口。我将不得不尝试转换它。
标签: c# inheritance