1579

I've read around about const and static readonly fields. We have some classes which contain only constant values. They are 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?

Ivan Gechev
  • 706
  • 3
  • 9
  • 21
Svish
  • 152,914
  • 173
  • 462
  • 620
  • 7
    Here's a very interesting single case I just found in favor of `static readonly`: [try using a const inside an `IEnumerator` which would trigger an *unrecheable* `yield` and you'll get a dreaded "Internal compiler error"](http://answers.unity3d.com/questions/486902/internal-compiler-error-warning-cs0162-unreachable.html#answer-486904). I didn't test the code outside Unity3D, but I trust this is either a *mono* or *.NET* **bug**. It is a *c#* issue nevertheless. – cregox Jul 04 '13 at 20:13
  • 4
    possible duplicate of [What is the difference between const and readonly?](http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly) – nawfal Oct 22 '13 at 07:04
  • 10
    another difference is that you can use a const string in a switch, but not a static readonly string – flagg19 Apr 24 '15 at 10:13
  • 9
    `static readonly` can't be used in `switch-case` statement as `case` variable, `const` is required for this purpose. – Mostafiz Rahman May 01 '15 at 11:20
  • 4
    `static readonly` can't be used as attribute parameter, too – Dread Boy Nov 22 '17 at 05:57
  • for complete details https://enlear.academy/const-vs-readonly-vs-static-readonly-in-c-755c20aa0b57 – Trident Jan 09 '23 at 16:14

22 Answers22

1062

public static readonly fields are a little unusual; public static properties (with only a get) would be more common (perhaps backed by a private static readonly field).

const values are burned directly into the call-site; this is double edged:

  • it is useless if the value is fetched at runtime, perhaps from config
  • if you change the value of a const, you need to rebuild all the clients
  • but it can be faster, as it avoids a method call...
  • ...which might sometimes have been inlined by the JIT anyway

If the value will never change, then const is fine - Zero etc make reasonable consts ;p Other than that, static properties are more common.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 18
    Why a property over a field? If it's an immutable class, I see no difference. – Michael Hedgpeth Apr 16 '09 at 11:32
  • 84
    @Michael - same reasons as always; it hides the implementation. You may find (later) that you need to be lazy loaded, configuration based, a facade, or whatever. In reality, either would often be fine... – Marc Gravell Apr 16 '09 at 11:34
  • What do you mean by the constant is useless at runtime. So the Runtime can't read constants that are pulling key values from an app.config or web.config? – PositiveGuy Nov 28 '11 at 03:32
  • 52
    @CoffeeAddict by definition, a constant **is not** pulling values from a config file; it is burned in as a literal at compile-time. The only way you can use a constant *at runtime* is via reflection over the fields. Any other time you try to use it, the compiler **as already** substituted your *constant* usage for *literal* usage; i.e. if a method in your code uses 6 constants, and you inspect it as IL, there will be no mention of any constant lookups; the literal values will simply be loaded in-situ – Marc Gravell Nov 28 '11 at 06:25
  • 45
    @MarcGravell - CAUTION: `readonly` fields cannot be used in switch/case statements, instead you need them to be `const`. – Luciano May 01 '12 at 15:53
  • @Luciano: Are you sure about this? I just compiled some code as class MyClass{ public readonly string f; MyClass{f = "a"; switch(f){ case "a" class MyClass { public readonly string f; MyClass() { f = "a"; switch (f) { case "a": break; default: break; } } }: break; default: break; } } } – MPavlak Jul 11 '12 at 13:57
  • 1
    @user652688: Yes. I'm sure. Try to use a readonly variables inside case statement. Case statements need constant value not dynamically determined values, such as readonly variables which can have their values changed (determined dynamically) during the execution of your code. – Luciano Jul 11 '12 at 14:52
  • 2
    @user652688: Explaining in another way: switch statement expects a variable value to be checked against constants values (case statements). So readonly variables cannot be used as a constant in case statements. – Luciano Jul 11 '12 at 14:56
  • 6
    @Luciano: I see what you mean now, you can switch on readonly variables, but you cannot use the readonly variable as the case. that makes sense, but was a little unclear at first. – MPavlak Jul 16 '12 at 11:26
  • @MarcGravell Isn't the whole point of properties so that you can start with a field, and if you later on need to add functionality, change to a property without breaking the API? Since the property is used like a Field the change is transparent. I thought that was the entire point of Properties over method mutators and accessors. – Didier A. Aug 23 '13 at 15:28
  • 10
    @didibus Changing a field to a property does, in fact, break the API. A field in C# effectively acts like a variable, while a property in C# is a syntax helper for writing a getter method and/or a setter method. This difference is important when other assemblies are involved. If you change a field to a property, and other assemblies depended on this field, then those other assemblies have to be recompiled. – Stephen Booher Aug 26 '13 at 15:50
  • 4
    @MarcGravell why are Public static readonly fields a little unusual? – Talal Yousif Feb 02 '15 at 12:15
  • 6
    @TalalYousif all `public` fields are a little unusual; most fields are `private` - and for good reasons. `const`s are often `public`, sure, but that's different. If you are routinely exposing `public` fields, I suggest that is a mistake – Marc Gravell Feb 02 '15 at 14:24
280

I would use static readonly if the Consumer is in a different assembly. Having the const and the Consumer in two different assemblies is a nice way to shoot yourself in the foot.

Green Falcon
  • 818
  • 3
  • 17
  • 48
Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • 7
    So I think as some have mentioned or alluded to, it may be wise to only use const for values that are actually well known constants if they are made public otherwise they should be reserved for internal, protected, or private access scope. – jpierson Mar 09 '11 at 18:38
  • 2
    @Dio The reason it's still existing is because it is not an issue per se - it's something to be aware of, but the ability to inline consts across assembly boundaries is a good thing for performance. It's really just a matter of really understanding that "constant" means "it will never change". – Michael Stum Feb 27 '14 at 03:02
  • 1
    @MichaelStum Ok I should not call it "an issue". In my line of work, I do have const and share it across assemblies but I recompile for each deployment or code shipment. Nevertheless, this fact definitely worth to take note of it. – Dio Phung Feb 27 '14 at 07:41
  • 1
    So, in general, `internal const` or `public static readonly` depending on desired visibility. – Iiridayn Jul 20 '17 at 21:32
  • @Iiridayn There are two vastly different concepts in those statements. Visibility is regulated by `public` or `internal` (and [other access modifiers](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers)). The second concept is `static readonly` vs `const`, which regulates if a field is a constant or a variable. You can mix and match visibility and const-ness based on your use case. – Michael Stum Jul 20 '17 at 21:34
  • @MichaelStum my implication was that it seems you shouldn't generally use `public` with `const`, preferring `static readonly` if you need a `public` field. – Iiridayn Jul 21 '17 at 22:36
  • 2
    @Iiridayn Yeah, that's not a bad way of looking at it. There are a few edge-cases to consider (e.g., if using Reflection, or if a value is needed on an attribute), and there are valid uses for `public const` (e.g., anything part of a standard. Anytime I work with XML, there's a namespaces file with a bunch of `public const string`.) But in general, `public const` should only be used after considering the implications properly. – Michael Stum Jul 22 '17 at 18:41
  • 1
    Following up years later, in my experience the chances of simply replacing an assembly with another version without rebuilding the client app is minimal. Not impossible, but I see so many readonly statics declared because developers have read "it's good practice" rather than considering the audience and whether it's genuinely constant. If it really is something you might change the value of some day, go with static. Never change, const may be fine. – tjmoore Jan 21 '20 at 19:08
226

A few more relevant things to be noted:

const int a

  • must be initialized.
  • initialization must be at compile time.

readonly int a

  • can use a default value, without initializing.
  • initialization can be done at run time (Edit: within constructor only).
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter
  • 47,963
  • 46
  • 132
  • 181
218

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:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

prints out True, whereas:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

writes False.

The reason is that the method x.Equals has two overloads, one that takes in a short (System.Int16) and one that takes an object (System.Object). Now the question is whether one or both apply with my y argument.

When y is a compile-time constant (literal), the const case, it becomes important that there does exist an implicit conversion from int to short provided that the int is a constant, and provided that the C# compiler verifies that its value is within the range of a short (which 42 is). See Implicit constant expression conversions in the C# Language Specification. So both overloads have to be considered. The overload Equals(short) is preferred (any short is an object, but not all object are short). So y is converted to short, and that overload is used. Then Equals compares two short of identical value, and that gives true.

When y is not a constant, no implicit conversion from int to short exists. That's because in general an int may be too huge to fit into a short. (An explicit conversion does exist, but I didn't say Equals((short)y), so that's not relevant.) We see that only one overload applies, the Equals(object) one. So y is boxed to object. Then Equals is going to compare a System.Int16 to a System.Int32, and since the run-time types do not even agree, that will yield false.

We conclude that in some (rare) cases, changing a const type member to a static readonly field (or the other way, when that is possible) can change the behavior of the program.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • 21
    A good addition to the accepted answer. I would like to add that proper conversion of data types and other similar guidelines (like try catches etc) should be a staple of experienced programmers and not left to the compiler. Nevertheless, I learnt something new from here. Thank you. – Uknight Oct 17 '13 at 10:35
  • 2
    Wow, I've been programming in C# for a long time and I never would have guessed that a const int within the range of a short could be implicitly converted to a short. I must say that is rather odd. I love C# but these weird inconsistencies that don't seem to add much value but add a lot of required brain power to constantly consider can be annoying, especially for beginners. – Mike Marynowski Jul 24 '18 at 10:50
  • 4
    @MikeMarynowski True enough. But I think they made that rule (among other reasons) to make the statement `short x = 42;` legal. Because there you have an `int`, namely the literal `42`, which is implicitly turned into the `short x`. But then, they might have restricted this to just numerical literals; however, they chose to allow also things like `short x = y;` where `y` is defined as `const int y = 42;`, and then they ended up with this. – Jeppe Stig Nielsen Jul 24 '18 at 11:14
100

One thing to note is const is restricted to primitive/value types (the exception being strings).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris S
  • 64,770
  • 52
  • 221
  • 239
  • 33
    Actually `const` could be used for other types too, except that it has to be initialized to null, which makes it useless :) – nawfal Oct 22 '13 at 06:58
  • 6
    exception as in `System.Exception`? :) – Memet Olsen Jan 06 '14 at 14:32
  • 5
    @nawfal More precisely, the only **value types** for which `const` can be used, are `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool`, plus any `enum` types. `const` cannot be used for other value types, like `DateTime` or `TimeSpan` or `BigInteger`. It also cannot be used for the `IntPtr` struct (considered a "primitive" type by some; the term primitive type is confusing in C#). ↵↵ The `const` can be used for all **reference types**. If the type is `string`, any string value can be specified. Otherwise, the value must be `null`. – Jeppe Stig Nielsen Sep 16 '15 at 08:15
  • 2
    @JeppeStigNielsen - I [recently had an argument](http://stackoverflow.com/a/34075993/1364007) with [servy](http://stackoverflow.com/users/1159478/servy) about this - he pointed out that you can make **anything** (value and reference types) `const` using [`default`](https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx). For `struct` types, it's an instance with all its members set to the default values. – Wai Ha Lee Dec 24 '15 at 11:36
40

Static Read Only:

The value can be changed through a static constructor at runtime. But not through a member function.

Constant:

By default static. A value cannot be changed from anywhere (constructor, function, runtime, etc. nowhere).

Read Only:

The value can be changed through a constructor at runtime. But not through a member function.

You can have a look at my repository: C# property types.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yeasin Abedin
  • 2,081
  • 4
  • 23
  • 41
32

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly 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 a const field is a compile-time constant, the readonly field can be used for runtime constants

From this short and clear MSDN reference.

Pang
  • 9,564
  • 146
  • 81
  • 122
yazanpro
  • 4,512
  • 6
  • 44
  • 66
23

const and readonly are similar, but they are not exactly the same.

A const field is a compile-time constant, meaning that that value can be computed at compile-time. A readonly field enables additional scenarios in which some code must be run during construction of the type. After construction, a readonly field cannot be changed.

For instance, const members can be used to define members like:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

Since values like 3.14 and 0 are compile-time constants. However, consider the case where you define a type and want to provide some pre-fab instances of it. E.g., you might want to define a Color class and provide "constants" for common colors like Black, White, etc. It isn't possible to do this with const members, as the right hand sides are not compile-time constants. One could do this with regular static members:

public class Color
{
    public static Color Black = new Color(0, 0, 0);
    public static Color White = new Color(255, 255, 255);
    public static Color Red   = new Color(255, 0, 0);
    public static Color Green = new Color(0, 255, 0);
    public static Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

But then there is nothing to keep a client of Color from mucking with it, perhaps by swapping the Black and White values. Needless to say, this would cause consternation for other clients of the Color class. The "readonly" feature addresses this scenario.

By simply introducing the readonly keyword in the declarations, we preserve the flexible initialization while preventing client code from mucking around.

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red   = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

It is interesting to note that const members are always static, whereas a readonly member can be either static or not, just like a regular field.

It is possible to use a single keyword for these two purposes, but this leads to either versioning problems or performance problems. Assume for a moment that we used a single keyword for this (const) and a developer wrote:

public class A
{
    public static const C = 0;
}

and a different developer wrote code that relied on A:

public class B
{
    static void Main() => Console.WriteLine(A.C);
}

Now, can the code that is generated rely on the fact that A.C is a compile-time constant? I.e., can the use of A.C simply be replaced by the value 0? If you say "yes" to this, then that means that the developer of A cannot change the way that A.C is initialized -- this ties the hands of the developer of A without permission.

If you say "no" to this question then an important optimization is missed. Perhaps the author of A is positive that A.C will always be zero. The use of both const and readonly allows the developer of A to specify the intent. This makes for better versioning behavior and also better performance.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
16

My preference is to use const whenever I can, which, as mentioned in previous answers, is limited to literal expressions or something that does not require evaluation.

If I hit up against that limitation, then I fallback to static readonly, with one caveat. I would generally use a public static property with a getter and a backing private static readonly field as Marc mentions here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter Meyer
  • 25,711
  • 1
  • 34
  • 53
13

Const: Constant variable values have to be defined along with the declaration and after that it won't change.const are implicitly static, so without creating a class instance we can access them. This has a value at compile time.

ReadOnly: We can define read-only variable values while declaring as well as using the constructor at runtime. Read-only variables can't access without a class instance.

Static readonly: We can define static readonly variable values while declaring as well as only through a static constructor, but not with any other constructor. We can also access these variables without creating a 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 the below blog post:

Const Strings – a very convenient way to shoot yourself in the foot

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1756922
  • 209
  • 2
  • 5
  • 1
    Could you plz tell me why did you downvote the answer ,so i can update myself as well as here. – user1756922 Sep 27 '18 at 15:42
  • 1
    Not the DV, but it may be that this answer doesn't really add anything to the already comprehensive answers here. – Marc L. Oct 29 '18 at 15:34
  • indeed, remember in Java back in the late 90's we had in a project multiple people producing different jars with class files that interoperated (referenced each other) and public const string had versioning trouble, since they were being copied around – George Birbilis Jun 10 '19 at 11:33
11

A static readonly field is advantageous when exposing to other assemblies a value that might change in a later version.

For instance, suppose assembly X exposes a constant as follows:

public const decimal ProgramVersion = 2.3;

If assembly Y references X and uses this constant, the value 2.3 will be baked into assembly Y when compiled. This means that if X is later recompiled with the constant set to 2.4, Y will still use the old value of 2.3 until Y is recompiled. A static readonly field avoids this problem.

Another way of looking at this is that any value that might change in the future is not constant by definition, and so should not be represented as one.

Yagnesh Cangi
  • 393
  • 3
  • 17
9

Const: Const is nothing but "constant", a variable of which the value is constant but at compile time. And it's mandatory to assign a value to it. By default a const is static and we cannot change the value of a const variable throughout the entire program.

Static ReadOnly: A Static Readonly type variable's value can be assigned at runtime or assigned at compile time and changed at runtime. But this variable's value can only be changed in the static constructor. And cannot be changed further. It can change only once at runtime

Reference: c-sharpcorner

Community
  • 1
  • 1
mayank
  • 2,615
  • 2
  • 23
  • 18
8

There is a minor difference between const and static readonly fields in C#.Net

const must be initialized with value at compile time.

const is by default static and needs to be initialized with constant value, which can not be modified later on. It can not be used with all datatypes. For ex- DateTime. It can not be used with DateTime datatype.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

readonly can be declared as static, but not necessary. No need to initialize at the time of declaration. Its value can be assigned or changed using constructor once. So there is a possibility to change value of readonly field once (does not matter, if it is static or not), which is not possible with const.

Chirag
  • 4,046
  • 1
  • 33
  • 24
5

const:

  1. value should be given upon declaration
  2. compile time constant

readonly:

  1. value can be given upon declaration or during runtime using constructors.The value may vary depend upon the constructor used.
  2. run time constant
dasumohan89
  • 103
  • 2
  • 8
2

A const (being determined at compile-time) can be used in cases where a readonly static can't, like in switch statements, or attribute constructors. This is because readonly fields are only resolved at run-time, and some code constructs require compile time assurance. A readonly static can be calculated in a constructor, which is often an essential and useful thing. The difference is functional, as should be their usage in my opinion.

In terms of memory allocation, at least with strings (being a reference type), there seems to be no difference in that both are interned and will reference the one interned instance.

Personally, my default is readonly static, as it makes more semantic and logical sense to me, especially since most values are not needed at compile time. And, by the way, public readonly statics are not unusual or uncommon at all as the marked answer states: for instance, System.String.Empty is one.

DvS
  • 1,025
  • 6
  • 11
2

Another difference between declaring const and static readonly is in memory allocation.

A static field belongs to the type of an object rather than to an instance of that type. As a result, once the class is referenced for the first time, the static field would "live" in the memory for the rest of time, and the same instance of the static field would be referenced by all instances of the type.

On the other hand, a const field "belongs to an instance of the type.

If memory of deallocation is more important for you, prefer to use const. If speed, then use static readonly.

Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
2

Use const if you can provide a compile-time constant:

private const int Total = 5;

Use static readonly if you need your value evaluated during run-time:

private static readonly int GripKey = Animator.StringToHash("Grip");

This will give a compile error because it is impossible to get the value at compile-time.

private const int GripKey = Animator.StringToHash("Grip");
Guney Ozsan
  • 300
  • 3
  • 7
1

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 takes 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!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

There is one important question, that is not mentioned anywhere in the above answers, and should drive you to prefer "const" especially for basic types like "int", "string" etc.

Constants can be used as Attribute parameters, static readonly field not!

Azure functions HttpTrigger, not using HttpMethods class in attribute

If only microsoft used constants for Http's GET, POST, DELETE etc.

It would be possible to write

[HttpTrigger(AuthorizationLeve.Anonymous,  HttpMethods.Get)] // COMPILE ERROR: static readonly, 

But instead I have to resort to

[HttpTrigger(AuthorizationLeve.Anonymous,  "GET")] // STRING

Or use my own constant:

public class HttpConstants
{
    public const string Get = "GET";
}

[HttpTrigger(AuthorizationLeve.Anonymous,  HttpConstants.Get)] // Compile FINE!
UberFace
  • 445
  • 1
  • 4
  • 14
  • Not sure I'd call this particularly _important_ though. And for the given example, I'd just write `"GET"` instead since it's much shorter and not something that's going to change anyways. ‍♂️ – Svish Aug 27 '20 at 09:11
0

Const

  1. Can be applied only for fields. Value should be in code compile time.
  2. Suited for removing magic "strings","int/double", (primitive types) etc across the code which is known already before compiling the code.
  3. After compiling the value will be placed all over the compiled code wherever constant is used. So if you have a huge string used many places, then watch out before making it const. consider using static read only.

Static read only

  1. Static read only be applied for fields/props and static can be used for methods. (on side note)When static is applied to methods, the complied code does not pass the 'this' parameter to the method and hence you cannot access the instance data of the object.
  2. Suitable for values which may change after compiling the code. Like values initialized from configuration, during startup of application etc.
  3. After compiling the code, the ref to value is used in IL code and may be slower compared to using const, but compiled code is small

During Refactoring, All const can be safely converted to Static read only, but not vise versa as we have seen above when converted code may break as some static readonly variable could be initialized in constructors.

Santosh Karanam
  • 1,077
  • 11
  • 23
  • My understanding of string constants in C# is that the constant even if used in multiple places is a single string in memory. So a large string in a `const` would still only be a single value that is referenced in several places across code as mentioned in this answer: https://stackoverflow.com/a/12004049/5087364. The language used here: "After compiling the value will be placed all over the compiled code wherever constant is used." makes it sound like it uses more memory. – Digital Coyote Apr 27 '23 at 12:49
  • yes, that is correct. The const value is not reference type. It gets replaced at every place the const is used. I verified it with a small program here and checked the assembly code for you - https://github.com/santoshkaranam/constants – Santosh Karanam Apr 28 '23 at 14:37
0

One additional difference that I don't believe is mentioned above:

const and static readonly values don't get CodeLens applied to them in the Visual Studio IDE.

static get only properties DO get CodeLens applied to them.

Code Lens Example

I consider the addition of CodeLens to be quite valuable.

Note: Currently using Visual Studio 2022.

Mmm
  • 682
  • 9
  • 11
  • This seems to belong more to a thread "Property vs. field" than to the current question "Static readonly vs. const". And properties have other advantages too; you can make the logic under the `get` accessor more complicated later, without changing the "contract" with the consumer of the member. – Jeppe Stig Nielsen Apr 09 '23 at 22:53
0

Const, readonly, static readonly - keywords that perform a similar action but have an important difference:

Const - is a variable whose value is constant and is assigned at compile time. You must assign a value to it. The default constants are static, and we cannot change the value of the const variable throughout the program.

Readonly - means a value that we can change at run time, or we can assign it at run time, but only through a non-static constructor.

Static readonly - values ​​can be assigned at run time or assigned at compile time and changed at run time. But the value of this variable can be changed only in the static constructor. And cannot be changed further. It can only be changed once during execution.

Examples you can find here - https://www.c-sharpcorner.com/UploadFile/c210df/difference-between-const-readonly-and-static-readonly-in-C-Sharp/