jcolebrand
jcolebrand

Reputation: 16025

What is the underlying difference between these two types of property declaration?

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?

Upvotes: 2

Views: 129

Answers (4)

Reed Copsey
Reed Copsey

Reputation: 564413

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.

Upvotes: 9

Thom Smith
Thom Smith

Reputation: 14086

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.

Upvotes: 2

Servy
Servy

Reputation: 203820

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.

Upvotes: 2

Henk Holterman
Henk Holterman

Reputation: 273244

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

Upvotes: 1

Related Questions