I've read around about const
and static readonly
fields. We have some classes which contains only constant values. Used for various things around in our system. So I am wondering if my observation is correct:
Should these kind of constant values always be static readonly
for everything that is public? And only use const
for internal/protected/private values?
What do you recommend? Should I maybe even not use static readonly
fields, but rather use properties maybe?
I would use
static readonly
if the Consumer is in a different assembly. Having theconst
and the Consumer in two different assemblies is a nice way to shoot yourself in the foot.Constants are like the name implies, fields which don't change and are usually defined statically at compile time in the code.
Read only variables are fields that can change under specific conditions.
They can be either initialized when you first declare them like a constant, but usually they are initialized during object construction inside the constructor.
They cannot be changed after the initialization took place, in the conditions mentioned above.
Static read-only sounds like a poor choice to me since, if it's static and it never changes, so just use it public const, if it can change then it's not a constant and then, depending on your needs, you can either use read-only or just a regular variable.
Also, another important distinction is that a constant belongs to the class, while the read-only variable belongs to the instance!
This is just a supplement to the other answers. I will not repeat them (now four years later).
There are situations where a
const
and a non-const have different semantics. For example:prints out
True
, whereas:writes
False
.The reason is that the method
x.Equals
has two overloads, one that takes in ashort
(System.Int16
) and one that takes anobject
(System.Object
). Now the question is whether one or both apply with myy
argument.When
y
is a compile-time constant (literal), theconst
case, it becomes important that there does exist an implicit conversion fromint
toshort
provided that theint
is a constant, and provided that the C# compiler verifies that its value is within the range of ashort
(which42
is). See Implicit constant expression conversions in the C# Language Specification. So both overloads have to be considered. The overloadEquals(short)
is preferred (anyshort
is anobject
, but not allobject
areshort
). Soy
is converted toshort
, and that overload is used. ThenEquals
compares twoshort
of identical value, and that givestrue
.When
y
is not a constant, no implicit conversion fromint
toshort
exists. That's because in general anint
may be too huge to fit into ashort
. (An explicit conversion does exist, but I didn't sayEquals((short)y)
, so that's not relevant.) We see that only one overload applies, theEquals(object)
one. Soy
is boxed toobject
. ThenEquals
is going to compare aSystem.Int16
to aSystem.Int32
, and since the run-time types do not even agree, that will yieldfalse
.We conclude that in some (rare) cases, changing a
const
type member to astatic readonly
field (or the other way, when that is possible) can change the behavior of the program.The
readonly
keyword is different from theconst
keyword. Aconst
field can only be initialized at the declaration of the field. Areadonly
field can be initialized either at the declaration or in a constructor. Therefore,readonly
fields can have different values depending on the constructor used. Also, while aconst
field is a compile-time constant, thereadonly
field can be used for runtime constantsShort and clear MSDN reference here
public static readonly
fields are a little unusual;public static
properties (with only aget
) would be more common (perhaps backed by aprivate static readonly
field).const
values are burned directly into the call-site; this is double edged:If the value will never change, then const is fine -
Zero
etc make reasonable consts ;p Other than that,static
properties are more common.Const : const variable values have to define along with declaration and after that it won't change.const are implicitly static so without creating class instance we can access them. this has a value at compile time
ReadOnly: readonly variable values we can define while declaring as well as using the constructor at runtime. readonly variables cant access without class instance.
Static readonly: static readonly variable values we can define while declaring as well as only through static constructor but not with any other constructor.these variables also we can access without creating class instance(As static variables).
static readonly will be better choice if we have to consume the variables in different assemblies.Please check the full details in below link
https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/