Does C# resolve dependencies among static data members automatically? - c#

If one static data member depends on another static data member, does C#/.NET guarantee the depended static member is initialized before the dependent member?
For example, we have one class like:
class Foo
{
public static string a = "abc";
public static string b = Foo.a + "def";
}
When Foo.b is accessed, is it always "abcdef" or can be "def"?
If this is not guaranteed, is there any better way to make sure depended member initialized first?

Like said before, static field initialization is deterministic and goes according to the textual declaration ordering.
Take this, for example:
class Foo
{
public static string b = a + "def";
public static string a = "abc";
}
Foo.b will always result in "def".
For that matter, when there is a dependency between static fields, it is better to use a static initializer :
class Foo
{
public static string b;
public static string a;
static Foo()
{
a = "abc";
b = a + "def";
}
}
That way, you explicitly express your concern about the initialization order; or dependency for that matter (even if the compiler won't help if you accidentally swap the initialization statements.) The above will have the expected values stored in a and b (respectively "abc" and "abcdef").
However, things might get twisty (and implementation specific) for the initialization of static fields defined in multiple classes. The section 10.4.5.1 Static field initialization of the language specification talks about it some more.

It will show allways "abcdef", because initialization goes top down in source, today just like before.
All static members will be initialized upon loading of the classtype holding them.

Related

C#: create a variable retains its value for the duration of a program [duplicate]

How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);

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.

Trying to understand static constructors

I am trying to understand need for static constructors. None of information I found answered following question I have. Why would you do this
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
baseline = DateTime.Now.Ticks;
}
}
as opposed to this
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline = DateTime.Now.Ticks;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
//static SimpleClass()
//{
//}
}
?
This is not dupe of other question, this is about static constructors which don't accept parameters.
The need is somehow obvious: You want to do more than some field initialization for your static members.
Logically if you have this class:
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline = DateTime.Now.Ticks;
}
You can re-write it to have the same effect:
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
static SimpleClass () {
baseline = DateTime.Now.Ticks;
}
}
But instead, you could do more in your static constructor such as inspecting (using reflection) some properties and emiting some fast accessors / getters to them, or just simple notify other systems that your type has been created, etc.
From Jeffrey Richter CLR via C# book:
When the C# compiler sees a class with static fields that use inline
initialization (the BeforeFieldInit class), the compiler emits the
class’s type definition table entry with the BeforeFieldInit metadata
flag. When the C# compiler sees a class with an explicit type
constructor (the Precise class), the compiler emits the class’s type
definition table entry without the BeforeFieldInit metadata flag. The
rationale behind this is as follows: initialization of static fields
needs to be done before the fields are accessed, whereas an explicit
type constructor can contain arbitrary code that can have observable
side effects; this code may need to run at a precise time.
Obviouselly there is something more than this happening behind the scenes, I would suggest you to read entire chapter from CLR via C#: "Type Constructors"
This is an example of a possible difference:
class SimpleClass
{
static readonly long A = DateTime.Now.Ticks;
static readonly long B = DateTime.Now.Ticks;
static SimpleClass()
{
}
}
A and B are not guaranteed to be the same value, though if you were to write it in the constructor, you could guarantee it:
class SimpleClass
{
static readonly long A;
static readonly long B;
static SimpleClass()
{
var ticks = DateTime.Now.Ticks;
A = ticks;
B = ticks;
}
}
In addition, order matters for instantiation of static members.
According to ECMA-334 regarding static field initialization:
The static field variable initializers of a class declaration
correspond to a sequence of assignments that are executed in the
textual order in which they appear in the class declaration. If a
static constructor (§17.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
So, we can write something like this:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetNext();
public static readonly long B = IdentityHelper.GetNext();
static SimpleClass()
{
}
}
public static class IdentityHelper
{
public static int previousIdentity = 0;
public static int GetNext()
{
return ++previousIdentity;
}
}
Here, A is guaranteed to be assigned before B. In this example, A will be 1, and B will be 2. We can guarantee that A < B (assuming the identity does not overflow and there's no issues with threading). Now, if we re-order the fields:
public static readonly long B = IdentityHelper.GetNext();
public static readonly long A = IdentityHelper.GetNext();
The functionality changes. Thus, we've created a side-effect which is not immediately clear simply by re-ordering the fields definitions.
A more likely scenario is, we may want to do this:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetExpensiveResult().A;
public static readonly long B = IdentityHelper.GetExpensiveResult().B;
static SimpleClass()
{
}
}
Here, we're unable to share GetExpensiveResult() between the fields.

Understanding C# field initialization requirements

Considering the following code:
public class Progressor
{
private IProgress<int> progress = new Progress<int>(OnProgress);
private void OnProgress(int value)
{
//whatever
}
}
This gives the following error on compilation:
A field initializer cannot reference the non-static field, method, or property 'Progressor.OnProgress(int)'
I understand the restriction it is complaining about, but I don't understand why it is an issue, but the field can be initialized in the constructor instead as follows:
public class Progressor
{
private IProgress<int> progress;
public Progressor()
{
progress = new Progress<int>(OnProgress);
}
private void OnProgress(int value)
{
//whatever
}
}
What is the difference in C# regarding the field initialization vs constructor initialization that requires this restriction?
Field initialization come before base class constructor call, so it is not a valid object. Any method call with this as argument at this point leads to unverifiable code and throws a VerificationException if unverifiable code is not allowed. For example: in security transparent code.
10.11.2 Instance variable initializers
When an instance constructor has no constructor initializer, or it has a constructor initializer of the form base(...), that constructor implicitly performs the initializations specified by the variable-initializers of the instance fields declared in its class. This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor. The variable initializers are executed in the textual order in which they appear in the class declaration.
10.11.3 Constructor execution
Variable initializers are transformed into assignment statements, and these assignment statements are executed before the invocation of the base class instance constructor. This ordering ensures that all instance fields are initialized by their variable initializers before any statements that have access to that instance are executed.
Everything in my answer is just my thoughts on 'why it would be dangerous to allow that kind of access'. I don't know if that's the real reason why it was restricted.
C# spec says, that field initialization happens in the order fields are declared in the class:
10.5.5.2. Instance field initialization
The variable initializers are executed in the textual order in which
they appear in the class declaration.
Now, let's say the code you've mentioned is possible - you can call instance method from field initialization. It would make following code possible:
public class Progressor
{
private string _first = "something";
private string _second = GetMyString();
private string GetMyString()
{
return "this is really important string";
}
}
So far so good. But let's abuse that power a little bit:
public class Progressor
{
private string _first = "something";
private string _second = GetMyString();
private string _third = "hey!";
private string GetMyString()
{
_third = "not hey!";
return "this is really important string";
}
}
So, _second get's initialized before _third. GetMyString runs, _third get's "not hey!" value assigned, but later on it's own field initialization runs, and it's being set to `"hey!". Not really useful nor readable, right?
You could also use _third within GetMyString method:
public class Progressor
{
private string _first = "something";
private string _second = GetMyString();
private string _third = "hey!";
private string GetMyString()
{
return _third.Substring(0, 1);
}
}
What would you expect to be value of _second? Well, before field initialization runs all the fields get default values. For string it would be null, so you'll get unexpected NullReferenceException.
So imo, designers decided it's just easier to prevent people from making that kind of mistakes at all.
You could say, OK let's disallow accessing properties and calling methods, but let's allow using fields that were declared above the one you want to access it from. Something like:
public class Progressor
{
private string _first = "something";
private string _second = _first.ToUpperInvariant();
}
but not
public class Progressor
{
private string _first = "something";
private string _second = _third.ToUpperInvariant();
private string _third = "another";
}
That's seems useful and safe. But there is still a way to abuse it!
public class Progressor
{
private Lazy<string> _first = new Lazy<string>(GetMyString);
private string _second = _first.Value;
private string GetMyString()
{
// pick one from above examples
}
}
And all the problems with methods happen to come back again.
Section 10.5.5.2: Instance field initialization describes this behavior:
A variable initializer for an instance field cannot reference the
instance being created. Thus, it is a compile-time error to reference
this in a variable initializer, as it is a compile-time error for a
variable initializer to reference any instance member through a
simple-name
This behavior applies to your code because OnProgress is an implicit reference to the instance being created.
The answer is more or less, the designers of C# preferred it that way.
Since all field initializers are translated into instructions in the constructor(s) which go before any other statements in the constructor, there is no technical reason why this should not be possible. So it is a design choice.
The good thing about a constructor is that it makes it clear in what order the assignments are done.
Note that with static members, the C# designers chose differently. For example:
static int a = 10;
static int b = a;
is allowed, and different from this (also allowed):
static int b = a;
static int a = 10;
which can be confusing.
If you make:
partial class C
{
static int b = a;
}
and elsewhere (in other file):
partial class C
{
static int a = 10;
}
I do not even think it is well-defined what will happen.
Of course for your particular example with delegates in an instance field initializer:
Action<int> progress = OnProgress; // ILLEGAL (non-static method OnProgress)
there is really no problem since it is not a read or an invocation of the non-static member. Rather the method info is used, and it does not depend on any initialization. But according to the C# Language Specification it is still a compile-time error.

How to use Global Variables in C#?

How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);

Categories

Resources