问题
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