Storing and indexing constants in C#

风格不统一 提交于 2019-12-13 16:30:46

问题


Sort of a philosophical question, I guess.

We are starting a video game project, and discovering C# as we go. One of the first things we need is a way to store constants in a bunch of arrays, so that anyone can access those values easily, and so we can quickly add or modify values as new character or weapon types are defined.

Now in C++, this is how I've learned to do it:

  • declare an enum in some constants.h file, with its last element being "WHATEVER_TYPE_END" ;
  • declare constant arrays of size "WHATEVER_TYPE_END" since enums and array indices work well in C++ ;
  • fill these arrays with various values of different types in constants.cpp.

An example:

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];

It's neat, since it lets the programmer retrieve modifiers quite effortlessly. If I want to compute how much damage my character will do, I do something like

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

Now in C#, I've been trying to get my head around how to achieve a similar result. After three hours of peregrinations, I finally have something functionnal, but it looks somewhat hackish.

What I have is a static class (named Constants) where public enums are declared, and public static readonly arrays of size (int)SomeEnum.END are defined. Declaration looks like this:

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

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

Array is readonly and not const because of CS0134. The enum must be cast explicitly to an int, but otherwise it works fine. Now, I know those "constants" are not really constants, the values of these arrays may be changed ; I've found two possible solutions to this problem:

  • protecting the arrays, and using getters, returning a copy of the array if someone really needs the whole thing and not just one value ;
  • using ReadOnlyCollection

Since I'm biased towards my old C++ ways (which might themselves not be as clean as I like to imagine), none of these solutions appeals to me (particularly not ReadOnlyCollection, since I'm (mostly superstitiously, I guess...) afraid of time and/or memory overheads (we're dealing with a real-time multiplayer game)).

Mostly, I guess, I'm afraid the amount of effort I went through just to implement something almost-like-but-not-quite what I knew in another language is just a sign that I'm not doing things correctly. So, to anyone who has more experience with C# and/or video game making than I do, what would be the proper way to store a bunch of constants here?


回答1:


Does it really have to be constants? I mean you could wrap it in a class. I am not a big fan of using a lot of constants like that that depend on other constants. Your code is not very OO or readable. Of course there are exceptions if memory usage etc is a concern.

But the C# way of doing something like this would be doing it 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; }
}

etc.

Then having a factory method that initializes your weapons / characters etc when starting the game. The actual data could be stored anywhere like a file.




回答2:


I would suggest a "datastore" of some sort: DB, text files, spreadsheets, whatever strikes your fancy, that are loaded on startup. This makes testing various parameter combinations as easy as editing a row in the DB or textfile, etc, without any recompilation. Once the game becomes stable, then store these as resources in the EXE.



来源:https://stackoverflow.com/questions/15398215/storing-and-indexing-constants-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!