3

For a type like this:

public class BlurEffect
{
    public const string Name = "Blur";

    public int Amount {get;set;}
}

I have a few members like .Name, that will be the same across all members, should I make it static instead?

I just don't want it to be stored per instance, or use more resources than necessary, and they should also be read-only.

Lastly I want instance access for it so I can say:

blurEffect.Name

Should I make a Name property that returns a private static variable? Is this the best way?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689

4 Answers4

5

Constants, in C#, are actually resolved at compile time. They will be replaced with the value everywhere it's used by the compiler, so the "variable" (Name) won't actually exist in the resulting compiled IL.

String constants, in addition, get interned, so there is only one copy of "Blur" that will be loaded in your executable, no matter how many times its used.

Personally, I would use a private const and a public variable:

public class BlurEffect
{
    private const string name = "Blur";
    public string Name { get { return name; } }

    public int Amount {get;set;}
}

This gets you your instance-based usage, and still has a single constant you can manipulate.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Thanks but in this case, will "name" be stored per instance or just once for BlurEffect type like static variables? – Joan Venge Feb 11 '11 at 00:34
  • @Joan: I edited to explain a bit more. If you use a const, you'll get a single, constant string value in the string interning table, no matter how many times you use it. Strings are special that way... – Reed Copsey Feb 11 '11 at 00:36
  • Although now you said it like that. What happens for other types like int? Just curious. – Joan Venge Feb 11 '11 at 00:37
  • 1
    @Joan: At compile time, it will act just as if you put the "int" value there. So if you have a constant (ie: `private const int myConstant = 4;`), then write: `int myVariable = myConstant;`, it will compile exactly as if you wrote: `int myVariable = 4;` – Reed Copsey Feb 11 '11 at 00:40
  • Thanks Reed, last question: What would it do for custom types like const BlurEffect blur = new BlurEffect (6);? – Joan Venge Feb 11 '11 at 00:42
  • 3
    @Joan: That's not legal in C#. Constants must always be a value known at compile time. – Reed Copsey Feb 11 '11 at 00:44
  • 1
    Just out of curiosity, why did you opt to create a getter which returns a constant, rather than just have the constant public itself? – Rob Feb 11 '11 at 00:59
  • 3
    @Rob: By having a getter, you have something that will be inlined by the JIT, but allows you to later change this. It gets around the one downside of a constant (versioning), in case the assembly needs to change the value in the future. – Reed Copsey Feb 11 '11 at 01:09
  • 2
    Yup, Yup; this way, the constant value is only inlined into the property accessor, instead of into all other usages, which may be in other assemblies you don't think to recompile when you change the constant – KeithS Feb 11 '11 at 01:26
1

I personally have never seen any problem with public const variables. However, one thing to consider is if you later need to change the const into a non-constant (or need to do any form of processing when someone gets the value of the constant) then you will break your binary API.

Which means, if this is in the scope of a class library, then if you make such a change later, then every project that links to your class library must be recompiled. You can't just drop in the DLL to make such an update.

Earlz
  • 62,085
  • 98
  • 303
  • 499
  • 3
    Note that "const variable" is an oxymoron. Consts are by definition not variables. – Eric Lippert Feb 11 '11 at 00:38
  • Good one Eric, never though about that. Should one say "const value"? – Joan Venge Feb 11 '11 at 00:39
  • 1
    @Eric... well, oxymoron or not, it's how many people say it. "The class contains a constant value" just sounds weird. "The class contains a constant variable" doesn't, to me at least. Maybe we should take this over at english.se? :) – Earlz Feb 11 '11 at 00:41
  • 2
    I would say "The class contains a constant" - no need for anything else - the "constant" is a noun all on its own. – Reed Copsey Feb 11 '11 at 00:43
1

Constants in .NET are kinda weird. When you define a constant, the compiler enforces object-oriented conventions in your source code, but when the compiler creates the assemblies, any assembly that references this constant, including the assembly in which you declare it, gets the call to the constant reference replaced with a reference to the same value stored in the local assembly's manifest (which stores most "literals"). So, constants are effectively stored per-assembly, and are "static" to every use of that constant within the assembly. The problem is, if you change the constant, you must recompile any assembly that references the constant in order to refresh the manifests on the other assemblies.

Personally, in your case, I would define that value as static, and expose it through a property. This will prevent the value simply being embedded, and will instead place it in a static copy of the object that will be referenced from one place by any assembly in the current AppDomain that needs it (which basically means it's the same everywhere in the application, except for some special cases involving app pools or subdomains).

More info: How Constant Are Your Constants?

KeithS
  • 70,210
  • 21
  • 112
  • 164