在C#中存储和索引常量

时间:2013-03-13 23:05:59

标签: c# arrays constants

我想是一个哲学问题。

我们正在开始一个视频游戏项目,并在我们发现时发现C#。我们需要的第一件事就是将常量存储在一堆数组中,这样任何人都可以轻松访问这些值,因此我们可以在定义新角色或武器类型时快速添加或修改值。

现在在C ++中,这就是我学会了这样做的方法:

  • 在一些constants.h文件中声明一个枚举,其最后一个元素为“WHATEVER_TYPE_END”;
  • 声明大小为“WHATEVER_TYPE_END”的常量数组,因为枚举和数组索引在C ++中运行良好;
  • 在constants.cpp中使用不同类型的各种值填充这些数组。

一个例子:

enum FoulType {
    FOUL_TYPE_NONE,
    FOUL_TYPE_OUT_OF_PLAY,
    FOUL_TYPE_OFFSIDE,
    FOUL_TYPE_VIOLENCE,
    FOUL_TYPE_RETENTION,
    FOUL_TYPE_END
};

extern const char* FoulTypeNames[FOUL_TYPE_END];

extern const float FoulSanctionChances[FOUL_TYPE_END];

extern const ushort FoulSanctionSeconds[FOUL_TYPE_END];

extern const uchar FoulSanctions[FOUL_TYPE_END];

它很整洁,因为它让程序员可以毫不费力地检索修饰符。如果我想计算我的角色会做多少伤害,我会做类似

的事情
CharacterType charType = myCharacter.getType();
WeaponType weapType = myCharacter.getWeapon().getType();
damage = CharacterDamages[ charType ] * WeaponModifiers[ weapType ];

现在在C#中,我一直试图了解如何实现类似的结果。经过三个小时的旅行,我终于有了一些功能,但它看起来有点hackish。

我所拥有的是一个静态类(名为Constants),其中声明了公共枚举,并且定义了size(int)SomeEnum.END的公共静态只读数组。声明如下:

public enum WeaponType
{
    Gun = 0,
    Shotgun,
    Assault,
    End
};

public static readonly int[] WeapDamage = new int[ (int)WeaponType.End]
{
    10,
    50,
    10
};

由于CS0134,数组是readonly而不是const。枚举必须显式转换为int,否则它可以正常工作。现在,我知道那些“常量”并不是真正的常量,这些数组的值可能会改变;我找到了两个可能解决这个问题的方法:

  • 保护数组,并使用getter,如果有人确实需要整个数据而不仅仅是一个值,则返回数组的副本;
  • 使用ReadOnlyCollection

由于我偏向于旧的C ++方式(可能本身并不像我想象的那样干净),所以这些解决方案都没有吸引我(尤其不是ReadOnlyCollection,因为我(主要是迷信,我猜) ...)害怕时间和/或内存开销(我们正在处理实时多人游戏)。)

大多数情况下,我想,我担心我只是为了实现一些几乎像我在另一种语言中所知道的东西而付出的努力只是表明我没有正确地做事。 那么,对于那些比我更有C#和/或视频游戏制作经验的人来说,在这里存储一堆常数的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

它真的必须是常量吗?我的意思是你可以将它包装在一个类中。我不是很喜欢使用很多依赖于其他常量的常量。您的代码不是非常OO或可读。当然,如果关注内存使用等,也有例外。

但是做这样的事情的C#方式就是OO。

public class Weapon {
  public string Name { get; private set; }
  public WeaponType Type { get; private set; }
}

public class WeaponType {
  public string Name { get; private set; }
  public int Damage { get; private set; }
}

然后使用工厂方法在开始游戏时初始化你的武器/角色等。实际数据可以存储在任何文件中。

答案 1 :(得分:1)

我建议使用某种类型的“数据存储区”:数据库,文本文件,电子表格,无论你喜欢什么,都是在启动时加载的。这使得测试各种参数组合就像编辑DB或文本文件中的行一样简单,而无需重新编译。一旦游戏稳定,然后将这些资源存储在EXE中。