Why can't we define a constant variable as static? [duplicate] - c#

This question already has answers here:
Using consts in static classes
(4 answers)
Closed 9 years ago.
public static const string Var1 = "abc";//compile time error
public static readonly string Var2 = "def";
Why can't we define a constant as static ?

Constants are already static so that would be redundant and are resolved at compile time.
For example:
const X = 5;
int a = X + X;
Basically ends up as:
int a = 5 + 5;
However, the compiler optimizer will figure things out and actually emit 10.
See here for more information - http://msdn.microsoft.com/en-us/library/ms173119(v=vs.80).aspx

A const field already is static.
Everywhere you use it, its literal value is embedded in the generated IL.
Adding the static keyword at the point of declaration would be redundant.

From Static Classes and Static Class Members (C# Programming Guide):
Although a field cannot be declared as static const, a const field is essentially static in its behavior. It belongs to the type, not to instances of the type. Therefore, const fields can be accessed by using the same ClassName.MemberName notation that is used for static fields. No object instance is required.

Related

What is the real difference between a static member and a constant in C#?

I'm learning C#,and now i'm trying to understand static members and constants.Which is the best way to declare a constant?
This way?
class Myclass
{
public const double G=9.8;
}
Or
class Myclass
{
private static double G{get;set;}
static MyClass()
{
G=9.8;
}
}
I've asked this question because,with the 2 ways i access the membre with the same code:
Console.WriteLine(Myclass.G);
constant:
Constant fields are defined at the time of declaration in the code
snippet, because once they are defined they can't be modified. By
default a constant is static, so you can't define them static from
your side.
It is also mandatory to assign a value to them at the time of
declaration otherwise it will give an error during compilation of the
program snippet. That's why it is also called a compile-time constant.
Explanation:
Consider ff. code:
void Sum(int j)
{
const int i = 9, k = 2;
const int A = i + k;
}
This will produce a result of 11, without showing any error since we already declared it at the initial point of declaration.
But how about:
void Sum(int j)
{
const int i = 9, k = 2;
//const int A = i + k;
Const int B = i + j;
}
This code snippet will take you toward a compile-time error, because there is no initialization, since it's evaluated at run time.
Points to Remember
Compile-time constant
Can't be declared static
Can't be modified or changed
Can be of any type of Access Modifier
Local scope
Needs to get initialized
Declared at the time of declaration
Static
The static keyword is used to declare a static member. If we are
declare a class as a static class then in this case all the class
members must be static too. The static keyword can be used effectively
with classes, fields, operators, events, methods and so on
effectively.
Consider ff. code:
class ReadOnly
{
static int i = 11;
public static void disp()
{
Console.WriteLine(i);
}
}
Explanation:
This code will show no error and produce a result (11), since we declared its value to be static at the time of declaration. So we can access it depending on our use in the program.
But how about this:
class ReadOnly
{
int i = 9;
public static void disp()
{
Console.WriteLine(i);
}
}
This snippet above will show an error, because we didn't declare a value for the static and we are trying to access it within a method. We can't do that.
Points to Remember:
Can't be used with indexers
Works with constructors too
By default it is private
Can be parameterized or public too
If its applied to a class then all the class members need to be static
You can read more about above explanation here: constant vs readonly vs static
Additional note for static methods.
Consider ff. code:
public class SomeClass {
public string SomeMethod() {
return "Hello, World.";
}
}
When you want to Access SomeMethod of SomeClass, you need to instantiate SomeClass first:
var some = new SomeClass();
string result = some.SomeClass(); //this will set result as "Hello, World."
Compared to a static method:
public class SomeClass {
public static string SomeMethod() {
return "Hello, World.";
}
}
When accessing SomeMethod, you don't need to instantiate SomeClass. You can access it directly by:
string result = SomeClass.SomeMethod(); //this will give "Hello, World."
Which is the best way to declare a constant?
Its not the best, its the only way: const double G = 9.8;.
Or (...) static double G { get; set; }
Thats not a constant! Constant means constant: 1 is a constant, 'c'is a constant, PI is a constant... they represent values that don't change, ever!. Your second implementation of G can change, therefore its not a constant.
Also, its important you notice that constants are known at compile time, there is no evaluation needed at runtime.
This is the reason why any reference type const (expect string which has specific compiler support through string literals) can only be initialized to null, any other option would need to be evaluated at runtime.
Its also the reason why only a finite set of value types can be declared as const too. All of them are existing types in the framework and.. surprise, surprise, they all have compiler literal constant support: 1, 'c', 9.8 or 0.25M but not 01/01/2017 (how else would the compiler know the values before runtime?).
Another interesting question you didn't make is: what about static readonly?
You can think of static readonly as "the poor man's" const. Its often used to circumvent the limitations const offers concerning what types and initializing values are allowed.
It is almost the same as a constant, but there are a few important and decisive differences:
It can change; although it is readonly, you can change it's value inside the static constructor of the declaring type. const can never change after initialized.
It is evaluated at runtime, not compile time as a true const.
Any type can be declared as a static readonly and initialized to any valid value as you would do with any regular field.
As a nittpicking side note, you shouldn't make G a constant ;). It changes, and quite a bit. G in Ecuador is different from G in the North Pole.
const variables are assigned values at time of definition.
They are available at compile time. You can even use a compile time evaluate-able expression at compile time. But once a value has been assigned to a const variable, it cannot be changed at any other time.
Using static field means the value will remain same for every user of the application, but this value can be changed by code in any of the classes, and it will change for every user of the application.
Do not use static for constants, use const only. const are by default static, and you cannot use static keyword with it.
Check this
void Main()
{
// You will not be able to change value for const variable.
Console.WriteLine(Myclass.G);
// You will be able to change value for static variable,
// and this change will impact all users of the application.
// For every user, this field will store value of 10 now.
// That will not be required or desired code behavior.
Myclass1.G = 10;
Console.WriteLine(Myclass1.G);
}
// Normal class with const field
class Myclass
{
public const double G=9.8;
}
//static class with static constructor
static class Myclass1
{
public static double G{get;set;}
static Myclass1()
{
G=9.8;
}
}
Read More
Here you are talking about two different things, and this is their definition from MSDN:
1- static modifier: To declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, finalizers, or types other than classes.
2- const keyword: To declare a constant field or a constant local. Constant fields and locals aren't variables and may not be modified. Constants can be numbers, Boolean values, strings, or a null reference. Don’t create a constant to represent information that you expect to change at any time.
So a static member is defined for a Class (for all its instances, and that's why you can access it directly from the name of the Class) but can be modified. a const field of class can not be modified.

How to have program wide constant variables

I have a c# program and I have some constant variables that I want to be accessible throughout the program. I won't need to change them at any point.
I have tried a static class and that worked well. I declared a 'static class' and had my variables inside as 'public static'.
The problem came when I wanted to use these unchanging variables in a case statement. Since this only accepts consts, it didn't work out too well.
The question is this: if I have a static class which does not have static variables within it, will this work just as well? This is going from public static to public const.
Thanks for your help.
Yes, consts by default are static.
It depends. Const can't be variables, they must be literals. If you're trying to assign a variable to the const such as a class you made then you have to keep it as static readonly. If you mean to assign a literal such as a number or a string then const is just fine.
A few examples:
public const int Number = 1; // this works; 1 is a literal
public const int Number = SomeClass.SomeProperty; // this does not work
public const int Number = SomeClass.SomeConst; // this works
public const SomeClass Var = new SomeClass(); // does not work
public const string Var = "test"; // this works as "test" is a literal.
If you are not using literals youre better of doing:
public static readonly SomeClass Var = new SomeClass ();
If you are using numeric literals another option is the enum which is basically a static class with some added features.
public enum MyConstants
{
VarOne, // defaults to 0
VarTwo, // defaults to next number (1)
VarThree // defaults to next number (2)
}

Initialization order of static readonly field [duplicate]

This question already has answers here:
Order of static constructors/initializers in C#
(4 answers)
Closed 8 years ago.
I'm curious of the C# spec says anything about the order of initializing static field's in C# 5 (.net4). For instance:
public class Test
{
public static readonly string A = "hi";
public static readonly string B = "bye";
public static readonly string DEFAULT = A;
}
In testing (Mono 2.x) they seem to be initialized in the order they appear in code. eg. As is, DEFAULT will have the value "hi", but if I move the definition for DEFAULT above A and B, it will be assigned NULL because A hasn't been assigned yet.
Is there a guarantee that the variables are initialized in order? Or is it up to the compiler?
Thanks.
It is in the order that they appear in. See here.
The static field variable initializers of a class correspond to a
sequence of assignments that are executed in the textual order in
which they appear in the class declaration.
Also, when you have a static constructor:
If a static constructor (Section 10.11) exists in the class,
execution of the static field initializers occurs immediately prior to
executing that static constructor. Otherwise, the static field
initializers are executed at an implementation-dependent time prior to
the first use of a static field of that class.

Is it possible to have a getter for a const?

Just curious, is there a way to have a getter for a constant variable? I have a sort of internal version number to ensure that two versions of a library are still speaking the same language, but I'd like the programmer to be able to check what version they're using. Right now I use:
private const Int16 protocol_version = 1;
public Int16 ProtocolVersion => protocol_version;
But I'd prefer to do it with just the const if there's a way.
You could declare a property with only a get accessor (without even declaring the set accessor, not even private):
private const Int16 protocol_version = 1;
public Int16 ProtocolVersion => protocol_version;
This is not the same as defining a constant only: the constant would be resolved at compile time, so if you update the library without recompiling the dependent program, the program would still see the "old" value. Consider this example:
// The class library
using System;
namespace MyClassLibrary {
public class X {
public const Int16 protocol_version = 1;
public Int16 ProtocolVersion => protocol_version;
}
}
// The program
using System;
using MyClassLibrary;
class Program {
static void Main(string[] args) {
var x = new X();
Console.WriteLine($"Constant: {X.protocol_version0}");
Console.WriteLine($"Getter: {x.ProtocolVersion}");
}
}
Now, compile the first time and execute the program. You will see
Constant : 1
Getter : 1
Then, modify protocol_version to 2, and recompile the class library only, without recompiling the program, then put the new class library in the program folder and execute it. You will see:
Constant : 1
Getter : 2
The fact is that if it's just a constant, the value is replaced at compile time.
I think that what you are actually looking for is a static readonly variable: in that way, you will avoid the compile-time const replacement, and the variable will not be modifiable after initialization:
public static readonly Int16 protocol_version = 1;
You have to keep in mind the reason for the existance of getters/setters. It is to control access to an encapsulated variable, specifically to control how a variable is changed and who can change it. Since a const is set only once and remains read-only on runtime there is no reason to create a property for it. Setting the constant to public is completely acceptable since it is not a private variable that needs to be protected.
If you really... really want to make it a property then just define it as a readonly property, skip the setter entirely:
public Int16 ProtocolVersion => protocol_version;
But just so we are clear, I would say normally you would have public constants with the same coding style as properties:
public const Int16 ProtocolVersion = 1
Just do:
public const Int16 protocol_version = 1;
This will provide a public getter as a const cannot have a setter.
Constants cannot be reassigned, hence why they are called constant therefore just make protocol_version public
private const Int16 protocol_version = 1;

How to make a variable (not class member) "read only" in C#

I'm new to the C# world and I can't find a method to declare read only variable in C# (something like declaring "const" variable in c++). Is there one?
I'll give you an example:
...
int f() { return x; } // x is not const member
...
void g() {
int readOnlyVar = f(); // is there a method to declare readOnlyVar as read only or const
// Some code in which I want to restrict access to readOnlyVar to read only
}
There isn't an identical analogue.
The readonly keyword allows the variable value to be mutated, but only in a constructor.
The const keyword means the value cannot mutate and needs to be a compile time constant and can only be one of the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type. (C# 4.0 spec §10.4).
And in c#, readonly only applies to fields and cannot be applied to local variables.
No, there exists no solution for your code-example.
const in C# is for compile-time constants and since your variable gets its value from a function, it's not known at compile-time.
The readonly keyword does kind of what you're looking for, but that's only for member variables in classes (and only allows variables to be set in the constructor of the class).
But, on the other hand, why would you ever need it? If your function is very long, it should be refactored into smaller functions. If it's not very long, then why would you need to enforce a rule like this? Just don't assign to readOnlyVar is probably my best suggestion for you I'm afraid.
There are two ways to set a variable as read only.
public class ClassA
{
private const int I = 5;
private readonly int J = 5;
}
The const keyword will set the value at compile time. The readonly keyword will set the value at construction. So, if you need different values for each instance, use readonly. Otherwise use const.
in c# we having const or readonly keyword to declare a constant.
const
A constant member is defined at compile time and cannot be changed at runtime. Constants are declared as a field, using the const keyword and must be initialized as they are declared. For example;
public class MyClass
{
public const double PI = 3.14159;
}
PI cannot be changed in the application anywhere else in the code as this will cause a compiler error.
readonly
A read only member is like a constant in that it represents an unchanging value. The difference is that a readonly member can be initialized at runtime, in a constructor as well being able to be initialized as they are declared. For example:
public class MyClass
{
public readonly double PI = 3.14159;
}
or
public class MyClass
{
public readonly double PI;
public MyClass()
{
PI = 3.14159;
}
}
Because a readonly field can be initialized either at the declaration or in a constructor, readonly fields can have different values depending on the constructor used. A readonly field can also be used for runtime constants as in the following example:
public static readonly uint l1 = (uint)DateTime.Now.Ticks;
Notes
readonly members are not implicitly static, and therefore the static keyword can be applied to a readonly field explicitly if required.
A readonly member can hold a complex object by using the new keyword at initialization.
readonly members cannot hold enumerations.
credit goes here:
http://www.dotnetspider.com/forum/69474-what-final-c-i-need-detailed-nfo.aspx
This is not a language feature, but you’re not the only person interested in such a feature. You do have some options, though. You might replace your method’s implementation with a class that has readonly member variables. This is a big pain, though, and really explodes the size of your code. (When you write lambdas or use async methods, C# does something similar to lift locals to class fields and turns your lambda or async method into methods on an autogenerated class. We are basically doing the same thing, but manually so that we can set readonly.)
class Scope
{
int x;
int f() => x; // x is not const member
void g()
{
new gImpl(f()).Run();
}
class gImpl
{
readonly int readOnlyVar;
public gImpl(
int readOnlyVar)
{
this.readOnlyVar = readOnlyVar;
}
public void Run()
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
readOnlyVar = 3;
}
}
}
Another alternative which requires less code but is still clunky is to abuse a feature of foreach. The foreach keyword does not let you assign to the iteration variable. So you could do something like this:
class Scope
{
int x;
int f() => x;
void g()
{
foreach (var readOnlyVar in new[] { f(), })
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS1656: Cannot assign to 'readOnlyVar' because it is a 'foreach iteration variable'
readOnlyVar = 3;
}
}
}
The foreach method makes it easier to use anonymous types, but you could use generics combined with type inference to use anonymous types with the class method.

Categories

Resources