tags:

views:

862

answers:

8

I have various constants that my program uses. Some are strings, some are ints, and some are doubles. What's the best way to store them? I don't think I want an Enum, because the data is not all the same type, and I want to manually set each value. Should I just store them all in an empty class, or is there a better way?

+14  A: 

IMO using a class full of constants is fine for constants. If they will change semi-occasionally I recommend using AppSettings in your config and the ConfigurationManager class instead.

Chris Marisic
+18  A: 

You probably could have them in a static class, with static read-only properties.

public static class Constants
{
   public static string SomeConstant { get { return "Some value"; } }
}
Daniel A. White
grrr.. 40 seconds faster on the draw :)
Raj More
+1, but even better if you can pull these from a resource file for localization.
Joel Coehoorn
Seems a bit wordy - why not static readonly strings?
emptyset
@Joel - only if the user ever sees the value.
Philip Wallace
This sounds good. Like emptyset said, is there any reason to use properties here instead of static readonly strings?
Matthew
Why readonly and not const? You are not setting the value at runtime, so there is no need to have them as readonly.
Philip Wallace
I like to have the property icon in intellesense tehe.
Daniel A. White
@Daniel A. White - lol
Philip Wallace
The problem with const is that any assemblies compiled against consts get local copies of those consts when they themselves are compiled; so if you change a value you must also recompile all assemblies dependent on your assembly defining the constants - therefore its often safer to go the readonly route. Properties instead of public static values gives you flexibility to add some programming logic in the future if you need it (i.e. read from localization) without changing the interface to your constant values.
cfeduke
+4  A: 

First, if your constants are to be used from multiple assemblies use static readonly variables. If they are used only in your assembly go ahead with const.

What I like to do is the following:

internal static class ColumnKeys
{
    internal const string Date = "Date";
    internal const string Value = "Value";
    ...
}
Marcel Gosselin
Why readonly if used across multiple assemblies?
Philip Wallace
Why does static readonly work better with multiple assemblies than const?
Matthew
Const values are copied from the source assembly into the compiled code. This means if you have to change a const value, all dependent assemblies MUST be recompiled against the new version. Safer and more convenient to use static readonly's.
cfeduke
A: 

An empty static class is appropriate. Consider using several classes, so that you end up with good groups of related constants, and not one giant Globals.cs file.

Additionally, for some int constants, consider the notation:

[Flags]
enum Foo
{
}

As this allows for treating the values like flags.

emptyset
A: 

Yes, a static class for storing constants would be just fine, except for constants that are related to specific types.

bruno conde
+3  A: 

Another vote for using web.config or app.config. The config files are a good place for constants like connection strings, etc. I prefer not to have to look at the source to view or modify these types of things. A static class which reads these constants from a .config file might be a good compromise, as it will let your application access these resources as though they were defined in code, but still give you the flexibility of having them in an easily viewable/editable space.

David Lively
A connection string isn't a constant, it's a setting. It could be that the OP *really* means settings too, rather than constants, but I don't see any evidence for it.
Jon Skeet
I beg to differ. String literals are constants by definition. Changing the string in a config file is roughly equivalent to changing it in code and recompiling; would *that* make it not a constant? I don't think so.
David Lively
@David - Not true. A compiler doesn't care about what value you have in your config file - this is read at runtime.
Philip Wallace
@PhilipW I understand that. My point was that (in response to Jon Skeet's comment) a specific connection string is a constant, as all string literals are. The fact that a "constant" can be changed - be that by modifying the config file, and having your app pull the new value from said config file, or by changing the literal in code which would require a recompile/deploy - doesn't make it a "setting." The string itself is constant regardless of its container. I understand and agree with your point - it just wasn't what I was saying.
David Lively
In my experience, at some point in the unforeseen future, your "constant" value will need to change even if you thought it would never in a million years. I think this is much easier to do in a .config file than changing the source code. Everything ends up being a setting in the end.
NinjaBomb
Absolutely. I think the confusion here is that we're attempting to differentiate between "constant" and "setting", which isn't as useful a distinction as it would have been in the past.
David Lively
+2  A: 

This is the best way IMO. No need for properties, or readonly:

public static class Constants
{
   public const string SomeConstant = "Some value";
}
Philip Wallace
If you are going to use const, expose as internal only. Do not make const public (even if you think your assemblies aren't going to be used external to your organization). Also properties give you programmatic flexibility for future expansion without the need to redefine your interface.
cfeduke
A: 

If these Constants are service references or switches that effect the application behavior I would set them up as Application user settings. That way if they need to be changed you do not have to recompile and you can still reference them through the static properties class.

Properties.Settings.Default.ServiceRef
Aaron