Why is static int always 0 when accessed from another class - c#

I have a class with a static int. I want that int, once set, to be accessible anywhere in my program.
public class MyClass
{
public static int myInt;
public MyClass()
{
myInt = 100;
new TestClass();
}
static void Main(string[] args)
{
new MyClass();
}
}
..but when I try to call it in another class
public class TestClass
{
public TestClass()
{
int testInt = MyClass.myInt;
}
}
..testInt is always 0, even when I check in debug mode and see that the static int was successfully set.
What am I doing wrong?

You never instantiate an instance of the class... so the constructor never gets fired.
What you want is a static constructor.. to initialize static members:
public class MyClass {
public static int myInt;
static MyClass() { // Static Constructor
myInt = 100;
}
}
A static constructor is guaranteed to be fired before any access to an object. Exactly when is undetermined.

Well either as #Simon Whitehead suggested or the best way for this kind of thing is to initialize it when declaring. So you can write it like this:
public static int myInt = 100;
as this is not dependent on anything else, you don't need to wait for constructor.

I can't see any problem in the OP, as the code indeed does the expected job:
Try adding Console.WriteLine(testInt); in the end of the TestClass constructor. If the code equals the one posted, it should output 100.

Related

c# how assign static class to instance variable?

Static members can't be called with instance, like instance.myStaticProperty.
Is there any way, that I can have an instance variable that will be an alias of static self class? like:
class myClass
{
public string a ="hello";
public static string b ="world";
public myClass myVariable = global::myClass; // <--- phseudo code
}
and i could call:
myClass instance= new myClass();
instance.myVariable.b; //
No, there is not. The closest you get is using a using.
Your static class definition:
class ClassA
{
public static string A = "A";
}
And to use it:
using StaticClassA = ConsoleApp1.ClassA;
class Program
{
static void Main(string[] args)
{
string a = StaticClassA.A;
}
}
Not too much to gain though, but it might ease your naming a little.
Another (somewhat cooler) option is a static using:
using static ConsoleApp1.StaticClassA;
class Program
{
static void Main(string[] args)
{
string a = A;
}
}
You're attempting to do an anti-pattern there.
Static properties are properties not defined in an instance (object) of that class, but by the class itself. And as such, you can access and modify them whenever you choose to, provided you have the required scopes to do so.
I don't see the problem in calling MyClass.StaticProperty = <some expression>, if indeed the functions the static property do, are static. If it's something part of the object, something you don't connect with the class itself, i.e it might be different for each instanced object of that class, then just turn it into a regular property instead.
Example of some static properties and methods:
public class DoMath
{
public static string Pi { get; private set; } = "3.14";
public static double X {get; set;}
public static double Y {get; set;}
public static double Sum() => X + Y;
}
DoMath.X = 3.5;
DoMath.Y = 4;
double result = DoMath.Sum();
Console.WriteLine($"Pi is equal to {DoMath.Pi}.");
If you truly wish something to be static, then don't try to make it non-static. Simply declare it as such.
Static members are shared across all instances of the class or all instances of Class Of T of same T.
So you can access static properties outside of class by using the ClassName.VarName or directly by the VarName from within the class.
You can access static fields and properties and methods from all non static methods.
You can also add an instance member mapping a static member.
Instances of a static thing can't exist in addition to the static existence itself.
So you can write this:
class myClass
{
public string a = "hello";
static public string b = "world";
public string B { get { return b; } set { b = value; } }
public void DoSomething()
{
b = "new world";
}
}
And use it like that:
myClass instance= new myClass();
instance.DoSomething();
myClass.b = "another world";
instance.B = "C# world";

Accessing Static Members of Static Members

Consider the following classes
class A
{
public static int i;
}
class B
{
public static A a{get;}=new A(); // without new A(), B.A will be null
}
now,
B.a gives a new instance of A and since the variable "i" of class A is static, I can not access "i" through B.a i.e B.a.i is compile time error.
I understand that if I do like below,
class B
{
static class A
{
static int i;
}
}
then I could do B.A.i.
So my question is how could I access static members of a static member of a class? Is it possible at all and is there any other pattern that I can use.
Also note that making class "A" as static and having class "B" as
class B
{
public static A a{get;}
}
gives a compile time error that "static type cannot be used as return type".
Since i is static member of A you can access it directly like
class B
{
public static A a {get;} = new A();
public int ii{get;} = A.i;
}
how could I access static members of a static member of a class?
If something is a member of a class -- static or not static -- that means it's either a value or a reference to an instance of something. Therefore, if you know you have an instance of a class but that class has static members itself, then just access those members statically:
class MyClass
{
public static string Value { get; }
}
string x = MyClass.Value;
You don't need to instantiate a class to access it's static members.
Simply you can try :
int value = A.i;
If you need, you can add a static class too :
public static class A
{
public static int i;
}
and you can use anywhere in your code like :
int value = A.i;

Is a static collection guaranteed to be initialized/populated before another class uses it?

Suppose I have these 2 classes:
public class A<T> where T : IEntityWithID, new()
{
private static EntityInfo entityInfo = B.GetEntityInfo(typeof(T));
private static IEnumerable TestCases
{
// Do work with entityInfo...
}
}
private static class B
{
private static IList<EntityInfo> entityInfoList = B.GetEntityList();
public static EntityInfo GetEntityInfo(Type type)
{
return entityInfoList.Single(e => e.Types.Contains(type));
}
private static IList<EntityInfo> GetEntityList()
{
// Builds a list of EntityInfo's...
}
}
Is the entityInfoList in class B guaranteed to be initialized and populated before B.GetEntityInfo() is called in class A?
Yes, it is guaranteed. Here's a snippet from MSDN:
The program cannot specify exactly when the class is loaded. However,
it is guaranteed to be loaded and to have its fields initialized and
its static constructor called before the class is referenced for the
first time in your program.
EDIT: As pointed out, you could end up in a situation where 2 static classes depend on each other for initialization which could get you in trouble, but as long as that's not the case, you're fine.
No, if you have circular dependencies it's possible to run code from a class before that class's static initialization has finished.
Here's a simple example of a static field initialized to 5, and yet an external class observes that field being null:
public class A
{
public static void Foo()
{
Console.WriteLine(B.bar == null);
}
}
public class B
{
public static readonly object bar = Foo();
public static object Foo()
{
A.Foo();
return 5;
}
}
private static void Main(string[] args)
{
var bar = B.bar;
}
This will print true.

What exactly are Static Constructor in C#?

I have couple of question regarding Static Constructor in C#.
What exactly are Static Constructor and how they are different from non-static Constructor.
How can we use them in our application ?
**Edited
public class Test
{
// Static constructor:
static Test()
{
Console.WriteLine("Static constructor invoked.");
}
public static void TestMethod()
{
Console.WriteLine("TestMethod invoked.");
}
}
class Sample
{
static void Main()
{
Test.TestMethod();
}
}
Output :
Static constructor invoked.
TestMethod invoked.
So, this means that static constructor will be called once. if we again call Test.TestMethod(); static constructor won't invoke.
Any pointer or suggestion would be appreciated
'
Thanks
Static constructors are constructors that are executed only ONCE when the class is loaded. Regular (non-static) constructors are executed every time an object is created.
Take a look at this example:
public class A
{
public static int aStaticVal;
public int aVal;
static A() {
aStaticVal = 50;
}
public A() {
aVal = aStaticVal++;
}
}
And consider this code:
A a1 = new A();
A a2 = new A();
A a3 = new A();
Here, static constructor will be called first and only once during the execution of the program. While regular constructor will be called three times (once for each object instantiation).
static constructors are usually used to do initialization of static fields for example, assigning an initial value to static fields.. Do keep in mind that you will only be able to access static members (methods, properties and fields) on static constructors.
If you need to "execute the static constructor multiple times", you can't do that. Instead, you can put the code you want to run "multiple times" in a static method and call it whenever you need. Something like:
public class A {
public static int a, b;
static A() {
A.ResetStaticVariables();
}
public static void ResetStaticVariables() {
a = b = 0;
}
}
You use them the same way you use instance constructors - to set default values. Only in this case you'll be initializing static fields, so static constructors get executed only once.
Be aware that the code in static constructor won't be executed until the first call to the class was made.
it runs when class is loaded.
It will print :
{
hi from static A
A
}
public class A{
static A{
print("hi from static A");
}
public A() {
print("A");
}
main() {
new A();
}
}

Passing static parameters to a class

As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.

Categories

Resources