Some questions about static constructors, methods and fields - c#

I have some questions about behaviour of static members:
1) Is there a difference when initializing static fields and static constructors? As of my knowledge static fields are initialized with program execution. Does members of static constructors behave same way, or they are initialized on first use:
MyClass.myStaticField;
or I must initialize MyClass first:
Myclass m = new MyClass(); // static constructor is called
MyClass.myStaticField; // and after that
2) As I do recall, static fields are not garbage collected? So is this a reason, why I should not be instanciating static methods? When I've read about this topic, most of the people claims, that you should use static methods when, you can choose between static and non-static.
3) Is there any issues that must be pointed when you derive a class from parent class having static constructor?
4) Just of a curiosity, can you dispose static member?

The difference between static field and constructor initialization is a bit complex as it's changed between framework versions. Jon did an indepth blog article on this subject that you should take a look at.
http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx
Static Fields are garbage collected just like normal values. That is they are collected when they can no longer be accessed. This can happen in a number of scenarios the most common of which is when an AppDomain unloads. Static fields are specific to an AppDomain so once it unloads it's members are eligable for collection (this may be different for AppDomain neutral types but I don't believe so).
It's perfectly legal to Dispose a static member although it can lead to some issues if you leave the disposed value in the field and hence accessible to the rest of the application (which may not realize it's disposed)

Static methods are not immune from garbage collection. Use them all you like.
A static field normally isn't garbage collected because it doesn't go out of scope. However, if you were to set a static field to null, the instance it used to reference would then be a candidate for garbage collection. You could even call Dispose on a static field before nulling it out.

Static and instance (non-static) fields have very different meanings, and it is important to understand them before deciding which to use.
A static variable or method belongs to a class, not to a particular instance of the class. There is one copy of it per class (no matter how many instances you create) and it can be accessed without an instance of the class. For example,
public class MyClass {
static int myInt = 5;
}
System.out.println(MyClass.myInt); // this prints 5
MyClass.myInt = 10;
System.out.println(MyClass.myInt); // this prints 10
An instance variable requires an instance of the class
public class MyClass {
private int myInt2;
public void setMyInt2(int val) {
myInt2 = val;
}
public int getMyInt2() {
return myInt2;
}
}
MyClass m1 = new MyClass();
MyClass m2 = new MyClass();
System.out.println(m1.getMyInt2()); // prints 0, the default value
System.out.println(m2.getMyInt2()); // prints 0, the default value
m1.setMyInt2(3);
m2.setMyInt2(5);
// each object operates on its own instance of the variable
System.out.println(m1.getMyInt2()); // prints 3
System.out.println(m2.getMyInt2()); // prints 5
Also, there is no such thing as a static constructor. There are constructors as well as static initializer blocks. A static initializer block is written as:
static {
// initialize some static members here
}
In general, use instance variables/methods when the values affect an individual instance of an object, and use static variables and methods when they do not.

You've tagged this as Java too, so a couple of Java perspectives.
1). In Java there is no concept of a static constructor, instead you can define blocks of code as static and they are run at the time the Class is prepared for use - after all, static fields are shared by all instances of the Class and so need t be initialised before we have any working instances.
2). Don't think of fields, static or otherwise, as being garbage collected - it's objects that get garbage collected. So if you have:
class MyClass {
private static OneThing x = new OneThing();
private Another y = new Another();
}
// some code
MyClass m = new MyClass(); // creates instance of MyClass
m = null;
// no one now references that instance of MyClass
You're not garbage collecting x and y, you're garbage collecting the OneThing and Another instances. This will happen when there are no references to those objects.
In the case of the Another referenced by y, that happens when the MyClass instance itself is garbage collected. But OneThing referenced by x will still be referenced for so long as MyClass is known to the JVM. BUT, classes themselves can be garbage collected, so it is possible for eventually that x reference to be removed and the OneThing object to be garbage collected.

Static constructors/initializers all happen at the same time (though fields get initialzed based on when they get accessed.)
Static methods are never instantiated -- they represent behavior, not state. Therefore they do not participate in garbage collection.
No. The base class' static constructor will be called, but that's hardly an "issue".
What do you mean by dispose? C# IDisposable? The answer is yes if the static field is holding an instance of something that implements that interface.

With regards to #1, it's intuitively obvious in Java anyway that you don't need to create instances of the class to use the static members. It would prevent the ability to have a class that is not meant to be instantiated (e.g. java.util.Collections).
Plus you'd have a contradiction with the most common singleton pattern:
public SomeSingletonClass {
public static final SomeSingletonClass instance = new SomeSingletonClass();
private SomeSingletonClass() {}
}

Related

Unclear behavior by Garbage Collector while collecting instance properties or fields of reachable object

Till today I was thinking that members of reachable objects are also considered to be reachable.
But, today I found one behavior which creates a problem for us either when Optimize Code is checked or application is executed in Release Mode. It is clear that, release mode comes down to the code optimization as well. So, it seems code optimization is reason for this behavior.
Let's take a look to that code:
public class Demo
{
public Action myDelWithMethod = null;
public Demo()
{
myDelWithMethod = new Action(Method);
// ... Pass it to unmanaged library, which will save that delegate and execute during some lifetime
// Check whether object is alive or not after GC
var reference = new WeakReference(myDelWithMethod, false);
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Console.WriteLine(reference.IsAlive);
// end - Check whether object is alive or not after GC
}
private void Method() { }
}
I simplified code a bit. Actually, we are using our special delegate, not Action. But the behavior is same. This code is written in mind with "members of reachable objects are also considered to be reachable". But, that delegate will be collected by GC asap. And we have to pass it to some unmanaged library, which will use it for some time.
You can test demo by just adding that line to the Main method:
var p = new Demo();
I can understand the reason of that optimization, but what is the recommended way to prevent such case without creating another function which will use that variable myDelWithMethod which will be called from some place? One, option I found that, it will work if I will set myDelWithMethod in the constructor like so:
myDelWithMethod = () => { };
Then, it won't be collected until owning instance is collected. It seems it can't optimize code in the same way, if lambda expression is setted as a value.
So, will be happy to hear your thoughts. Here are my questions:
Is it right that, members of reachable objects are also considered to
be reachable?
Why it is not collected in case of lambda expression?
Any recommended ways to prevent collection in such cases?
However strange this would sound, JIT is able to treat an object as unreachable even if the object's instance method is being executed - including constructors.
An example would be the following code:
static void Main(string[] args)
{
SomeClass sc = new SomeClass() { Field = new Random().Next() };
sc.DoSomethingElse();
}
class SomeClass
{
public int Field;
public void DoSomethingElse()
{
Console.WriteLine(this.Field.ToString());
// LINE 2: further code, possibly triggering GC
Console.WriteLine("Am I dead?");
}
~SomeClass()
{
Console.WriteLine("Killing...");
}
}
that may print:
615323
Killing...
Am I dead?
This is because of inlining and Eager Root Collection technique - DoSomethingElse method do not use any SomeClass fields, so SomeClass instance is no longer needed after LINE 2.
This happens to code in your constructor. After // ... Pass it to unmanaged library line your Demo instance becomes unreachable, thus its field myDelWithMethod. This answers the first question.
The case of empty lamba expression is different because in such case this lambda is cached in a static field, always reachable:
public class Demo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action <>9__1_0;
internal void <.ctor>b__1_0()
{
}
}
public Action myDelWithMethod;
public Demo()
{
myDelWithMethod = (<>c.<>9__1_0 ?? (<>c.<>9__1_0 = new Action(<>c.<>9.<.ctor>b__1_0)));
}
}
Regarding recommended ways in such scenarios, you need to make sure Demo has lifetime long enough to cover all unmanaged code execution. This really depends on your code architecture. You may make Demo static, or use it in a controlled scope related to the unmanaged code scope. It really depends.

In C#, do all static variables get initialized before the main() method is called?

The ones I am particularly concerned about are:
static variables in classes that are defined in referenced/dependency classes, contained in external DLLs. In my example, none of the types in that third party assembly is reference until later in the program. (let's say 5 min into execution).
Will the static variables of that third-party assembly only be loaded then?
Thanks,
rui
according to C# spec which says:
If a static constructor 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. The example
whiteout a static constructor you can not predict exactly when a static variable is initialized but they are guaranteed to be initialized before their first use. but for sure they are not initialized before you reference their assemblies
All static fields are initialized before they are first used. This can be done by a type initializer (static constructor) explicitly declared or implicitly provided by the compiler. Static fields that do not have a value assigned in the class declaration will be initialized to the default value of their corresponding type.
Be careful if your static fields are object references whose constructors may throw exceptions:
class Foo
{
public Foo() { throw new Exception("boom"); }
}
class Bar
{
private static Foo baz = new Foo();
public Bar()
{
//trying to create a Bar will throw TypeInitializationException
}
public static void BarNone()
{
//trying to call a static method on Bar will throw TypeInitializationException
}
}
You'll get a TypeInitializationException when Bar is first used (either constructed or when a static method on Bar is called), as shown above.

How i can use a static field to keep track of how many objects have been created from a particular class

iam using c# and have a question,how the static field is used to count the number of instances in a class,please calrify in terms of memory,thanks in advance.
To simply count the number of constructions, declare a static field and use Interlocked.Increment in your instance constructor to increment the static field in a thread-safe manner.
If you want to count live objects, you'll also need to Interlocked.Decrement that field in your finalizer (i.e. C# destructor). Note, however, that adding a finalizer will make objects go through the finalization queue, making the garbage collection less efficient.
Depending on how you define "live" object, you might alternatively be interested in adding Interlocked.Decrement in your IDisposable.Dispose implementation.
Simply add a counter to the constructor of your class
class MyClass
{
static int instanceCount = 0;
public MyClass()
{
instanceCount++;
}
}
The constructor runs every time an instance of the class is created. The static variable is shared by all instances of the created class.
You could use a constructor and destructor to achieve what you want, but you shouldn't really need to know how many instances of your class exist at any one time. It sounds like you're going about a problem in the wrong way.
class MyClass
{
static int instances = 0;
public MyClass()
{
instances++;
}
~MyClass()
{
instances--;
}
}
Note that a class's destructor won't be called immediately. It is up to the garbage collector to decide when it collects an instance of your class, and therefore when your destructor is called.
Something like
class someclass
{
private static int instanceCounter;
public someclass() { someclass.instanceCounter++; }
}

Why we do not need to call Static Methods through the object?

public static void callit(ref int var)
{
var++;
}
public static void main(Object sender, EventArgs e)
{
int num=6;
callit(ref num);
Console.WriteLine(num);
}
But if here method callit() would not be a static then I had to make object of class then call it.
That's correct. Non-static methods need to be called on an instance of an object. Even if the method doesn't actually use any other members of the object, the compiler still enforces the rule that instance methods require instances. Static methods, on the other hand, do not need to be called on an instance. That's what makes them static.
Exactly because that's the whole point of static methods.
Instance methods require to know which instance of the class you call the method on.
instance.Method();
and they can then reference instance variables in the class.
Static methods, on the other hand, don't require an instance, but can't access instance variables.
class.StaticMethod();
An example of this would be:
public class ExampleClass
{
public int InstanceNumber { get; set; }
public static void HelpMe()
{
Console.WriteLine("I'm helping you.");
// can't access InstanceNumber, which is an instance member, from a static method.
}
public int Work()
{
return InstanceNumber * 10;
}
}
You could create an instance of this class to call the Work() method on that particular instance
var example = new ExampleClass();
example.InstanceNumber = 100;
example.Work();
The static keyword though, means that you don't need an instance reference to call the HelpMe() method, since it's bound to the class, and not to a particular instance of the class
ExampleClass.HelpMe();
I think MSDN explains it very well
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.
You can find more details about this topic here
This is simply a matter of C# syntax, if I understand your question correctly. There is no ambiguity in using callit(ref num); in your example. It is known exactly what method to call, since it is a static method and there is no object attached. On the other hand, if callit was not static, the compiler would not know the object on which to call the method, since you are calling it from a static method (which has no object). So, you would need to create a new object and call the method on that object.
Of course, if neither method was static, the method call would operate on itself, and again, the object would be known so there is no problem.
Because static methods are associated with the class itself, not with a specific object instance.
Static functions work on classes.
Member functions work on instances.
And yes, you can only call a member function of an object (instance). No instance, no member.
Static methods are called on the type (or class), whereas non-static methods are called on the instance of a type i.e. object of a class.
You cannot call non-static methods or non-static variables in a static method, as there can be multiple objects (i.e. instances of the same type).
Static functions access class variables that are just as accessible by any other static functions AND instance functions. Meaning if you have a class variable called static int count, in static method static increaseCount() { count++; } increases the variable count by 1, and in static method static decreaseCount() { count--; } decreases the variable count by 1.
Therefore, both a static function and an instance function may access a static variable, but a static function MAY NOT access an instance variable.
Static functions are also called class functions.
Non static functions are also called instance functions.
Static method are independent of instance, suppose there is man class in that there is eat method which is non static and there is sleep method which is static then when you create different instance of man lets say man m1, m2. m1 and m2 share same sleep methods but different eat method. In java all static variables are stored in heap memory which is shared all object instances suppose at runtime if static variable changes then it will share on all instances of the object in our case.m1 and m2. But if you change non-static varible it will for only that object instance
m1.anStaticvariable = 1; // changes value of m2.anStaticvariable also
But
m1.nonStaticvariable = 1; //wont change m2.nonStaticvariable
Hope this helps you

Why can I only access static members from a static function?

I have a static function in a class.
whenever I try to use non static data member, I get following compile error.
An object reference is required for the nonstatic field, method, or property member
Why is it behaving like that?
A non-static member belongs to an instance. It's meaningless without somehow resolving which instance of a class you are talking about. In a static context, you don't have an instance, that's why you can't access a non-static member without explicitly mentioning an object reference.
In fact, you can access a non-static member in a static context by specifying the object reference explicitly:
class HelloWorld {
int i;
public HelloWorld(int i) { this.i = i; }
public static void Print(HelloWorld instance) {
Console.WriteLine(instance.i);
}
}
var test = new HelloWorld(1);
var test2 = new HelloWorld(2);
HelloWorld.Print(test);
Without explicitly referring to the instance in the Print method, how would it know it should print 1 and not 2?
Instance methods rely on state of that particular instance in order to run.
Let's say you had this class which has the scenario you describe:
class Person
{
static PrintName()
{
// Not legal, but let's say it is for now.
Console.WriteLine(Name);
}
private Name { get; set; }
}
Hopefully, the problem is apparent now. Because Name is an instance member, you need an actual instance of the class, since Name can be different across different instances.
Because of this, the static method, which is not attached to an instance, doesn't know which instance to use. You have to be explicit in specifying which one.
A static method cannot directly access any non-static member variables of a class.
After all : a static method can be called without an instance of the class even being in existance. How do you want to access a member variable on a non-existing instance??
(of course, as Mehrdad pointed out: you could pass an instance of your class to a static method and access everything on that instance - but that's not what you're talking about, right?)
Static functions can only use static members, and call static functions.
As mentioned, a static function can operate on a class instance, but not from within a class instance (for lack of a more descriptive word). For example:
class MyClass
{
public int x;
public static int y;
public static void TestFunc()
{
x = 5; // Invalid, because there is no 'this' context here
y = 5; // Valid, because y is not associated with an object instance
}
public static void TestFunc2(MyClass instance)
{
instance.x = 5; // Valid
instance.y = 5; // Invalid in C# (valid w/ a warning in VB.NET)
}
}
The definition of a "non static data member" would be an "instance data member". In other words non static members belong to a created instance of your class.
A static method does not run in the context of any specific instance of the class. Hence when you ask such a method to use a non static member it will have no idea which of the 0 or more instances of the class it should try to get the data from.
You can't access non-static data from a static function. This is because the static function can be called irrespective of whether there are any instantiated objects of the class. The non-static data, however, is dependent on a specific object (instantiation) of the class. Since you can't be sure that there are any objects instantiated when calling a static function, it is illogical (and therefore not allowed) to access non-static data from it.
This question has been asked several times on SO in different forms / for different languages:
C#
Java
Python
PHP
Language-independent

Categories

Resources