2

What is the main difference between the following two declarations?

public string Name
{
  get { return "Settings"; }
}

and

public const string Name = "Settings";

Aren't both prevented from being changed?

jcolebrand
  • 15,889
  • 12
  • 75
  • 121
  • 4
    The second is not a property. It's a const field. – Brian Rasmussen Oct 19 '12 at 17:07
  • I'm aware of http://stackoverflow.com/questions/653536/difference-between-property-and-field-in-c-sharp-net-3-5 and http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c – jcolebrand Oct 19 '12 at 17:07

4 Answers4

9

The first is a property which only provides a get accessor. This is specified per instance.

The second is a compile time constant. At compile time, it will be replaced with "Settings", so it is not really a member of the type at all.

The const declaration does have the advantage of eliminating a method call (as it's just a compile time constant value), however, the property call will likely get eliminated by the JIT at runtime.

The property declaration has the advantage of allowing you to change how this works later, without breaking compatibility - even binary compatibility. In order to see a change in the const value, a full recompilation of everything that uses it would be required, even if it's in separate assemblies.

Basically, a public const is probably a good idea, but only if this is a value that will never change - not a value that will never change during the runtime of the program, but that will never change anywhere, at any time. Int32.MaxValue is a good example - this has a specific meaning that is based on the Int32 type itself - there's no way that this would ever change. As such, it makes sense as a public const. In your case, "Settings" may be something you'd want to change eventually - if that's the case, then encapsulating it in a property makes sense.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • But for performance wise, in this situation, wouldn't we prefer the second option for memory and speed? Why would I chose the first option over the second? – jcolebrand Oct 19 '12 at 17:08
  • @jcolebrand Added that - basically, the property will likely get inlined by the JIT anyways, but it provides compatiblity later if you want to change the implementation. It's "safer" in terms of binary compat and versioning to use properties. – Reed Copsey Oct 19 '12 at 17:09
  • @jcolebrand In terms of memory, it'll be the same, really. In both cases, `"Settings"` will become an interned string (since it's a compile time constant), and only exist in one place in memory, so it's really just a matter of how this is accessed. – Reed Copsey Oct 19 '12 at 17:11
  • That actually cut to the heart of what I wanted to ask but wasn't sure about. Thanks Reed, I can always count on you for splendid advice and reassurance! – jcolebrand Oct 19 '12 at 17:11
  • In regard to the final comment about "if it might change" it would not change between compiles, only at compile time. This is specifically used to ID a module. In that way it becomes _like_ `Int32.MaxValue` for the module itself. – jcolebrand Oct 19 '12 at 17:22
  • @jcolebrand If this is used as ID from other assemblies, and changes with different compiles, I'd make it a property. A constant is good for things that *will never change* - ever. – Reed Copsey Oct 19 '12 at 17:30
  • I don't think I'm making myself clear. Why would we change the ID of the module except in the case of something drastic? (Personally I would've gone with assembly name but I didn't get to make this design decision). The name of the module should never change _in this environment_. Obviously others may have a different need. – jcolebrand Oct 19 '12 at 17:39
  • @jcolebrand Yes - if it's never changing, then it's likely fine as a constant. – Reed Copsey Oct 19 '12 at 19:06
2

The first is a property declaration. The second is an instance variable declaration.

Neither can be changed, but the semantics are different. In the case of the property, there isn't anything to change. When you use the shorthand syntax to declare a property (public string Name { get; }), it creates a hidden instance variable to hold the value of the property, but when you declare a property manually, as you have done here, and you don't declare an instance variable to go along with it, there is no data to be changed. In the example given, the property doesn't return the value of some variable containing "Settings", it returns the literal string. It is little different from a method returning a literal: it always returns the same value, but you wouldn't call it "immutable", per se, because "immutable" implies that there is something to be mutated.

In the case of the instance variable, you are creating a field that belongs to each instance of the class. Because of the const, the field's value cannot be modified, but there is an actual value stored that could, in principle, be modified but for that const.

Thom Smith
  • 13,916
  • 6
  • 45
  • 91
2

A const variable doesn't exist at runtime. The value of the field will, at compile time, be placed wherever that field is used. It would be the same as copy-pasting "Settings" wherever Name was used.

A read only property on the other hand exists at runtime. It will mean that a new property exists in that type, with the associated metadata. Each time the property is called it will call the method for the getter, involving the associated call stack manipulation, and that method will simply return the same value.

Using a const field will generally be preferable when it's possible to use it. The advantage of a read only property is that you could return something that's not a compile time literal.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

Aren't both prevented from being changed?

Yes, (only) in that respect they are the same.

But this property is very unusual, so the comparison seems artificial.

public string Name
{
  get { return "Settings"; }
}

You would not normally use a property for a design-time constant. If it is really fixed for the entire duration, use your second declaration (a constant, not a property):

public const string Name = "Settings";
H H
  • 263,252
  • 30
  • 330
  • 514
  • It is unusual, that's why it struck me as why wasn't it just a const. I figured I would ask the masses an interesting question. – jcolebrand Oct 19 '12 at 17:09
  • Can you provide a context for the property? Maybe that would shed a different light on it. But as is, without a virtual or even static modifier, it makes no sense. – H H Oct 19 '12 at 17:13
  • it's an override specifically, but I was thinking of the fact that it's never going to have a setter because it's a widget style class, so this is used to ID the class. – jcolebrand Oct 19 '12 at 17:13
  • As an override it makes some sense. – H H Oct 19 '12 at 17:16
  • Sure, but I was curious if there was an impact to the system like this in the long run as opposed to just making it not have an extra stack for the retrieval. – jcolebrand Oct 19 '12 at 17:18