Why must a static constructor be parameterless? - c#

I'm encountering this error:
'LnkScript.LnkScript.KillstreakHud.KillstreakHud(InfinityScript.Entity)': a static constructor must be parameterless C:\Users\home\Desktop\LnkScripts.cs 61 20 LnkScript
My source code:
public class KillstreakHud : BaseScript
{
static KillstreakHud(Entity player)
{
string killstreak = "^3Killstreak:^3" + player.GetField<int>("killstreak").ToString();
HudElem hudelem = HudElem.CreateFontString(player, "hudsmall", 1f);
HudElem.SetPoint("TOPCENTER", "TOPCENTER");
HudElem.SetText(killstreak);
base.OnInterval(300, delegate
{
killstreak = "^3Killstreak:^3" + player.GetField<int>("killstreak").ToString();
hudelem.SetText(Killstreak);
return true;
});
}
}
Clearly, my static constructor is not parameterless, and the compiler takes umbrage at this fact. But why?

A static constructor must be parameterless because nothing ever calls it, it is invoked when you access a static member or create an instance of the class, but not directly (it is called by the runtime).
The solution: Remove your parameters, or make it non-static
Reference for static constructors: http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
To make it non-static (note that it will need to be invoked directly with the new keyword now):
public KillstreakHud(Entity player)
{
...
}

In my opinion this is a limitation of the language. Static is something that is called once and does not change. There is no reason (apart from not implemented) why it cannot accept a parameter with the understanding that it will only ever use the parameter value once.
This limitation of the language is what has made such a mess in "public static class ConfigurationManager"
There are lost of people asking can I use a different config file?
If the constructor could accept a parameter then this would be easy
(but it can't so you have to make your own config)

The main purpose of declaring a data member static is that it should be available in all instances of the class. When a data member is shared among different instances it is imperative that data should be consistent among all the instances of the class.
And also there is no way to call static constructor explicitly.
Therefore the purpose of having a parameterized static constructor is useless.
a static constructor is implicitly called when:-
1. static data member is referenced.
or
2.object of the class containing static constructor is created.
visit https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

Related

Private vs Static constructors in .Net

I searched for this a lot, but none of the answers are clear (at-least for me!). Now I'm putting this question in SO, as I believe I can't get a more clarified answer anywhere else.
When should I use a private/static constructor in my class?
I'm fed up of usual answers, so please help me with some real-time examples and advantages/disadvantages of using these constructors.
Static constructors: used for initialising static members.
Private constructors: used when you only want a class to be instantiated from within its own code (typically in a static method). For example:
public class Thing
{
static int Number;
static Thing()
{
Number = 42; // This will only be called once, no matter how many instances of the class are created
}
// This method is the only means for external code to get a new Thing
public static Thing GetNewThing()
{
return new Thing();
}
// This constructor can only be called from within the class.
private Thing()
{
}
}
When should I use a private constructor in my class?
When you want a constructor, but don't want to expose it to the world. This could be because you have a factory method that calls the constructor (after validation), or because that constructor is called by ctor-chaining (i.e. public Foo(string) : this() { ...}).
Additionally, note that reflection code is often able to use a private constructor - for example serialization or ORM libraries.
Also, in early C# compilers, when you are writing what would now be a static class - having a private constructor was the only way of making it appear uncreatable.
When should I use a static constructor in my class?
When you need to initialize some static state prior to that state being accessed by instances or static methods.
Static constructor is used to intialize the static members of the class and is called when the first instance of the class is created or a static member is accessed for the first time.
Private constructor is used if you have overloads of the constructor, and some of them should only be used by the other constructors

Why doesn't the MessageBox class have a default constructor in C#?

Case 1:
I am trying this
MessageBox m = new MessageBox();
And got compilation error
'System.Windows.Forms.MessageBox' has no constructors defined
Case 2:
Then, I have made a class without constructor
class myClass
{
}
and tried myClass my = new myClass(); This time I found no error.
Now, my question:
Why I am getting error in 1st case?
Since, both are classes and every class have default constructor, then
Where is default constructor in 1st case?
The constructor may be private or protected in order to forbid direct instantiation. Use the static factory method instead. There is a static method Show in the MessageBox class.
Archil is right, too. If theres a explicit constructor defined, the implicit default constructor is not created anymore.
And regarding x0ns comments: Yes, it's also impossible to instantiate static classes. Don't use static classes, thats poor design (there are exceptions).
In c#, evey class automatically has default constructor if NONE is defined. MessageBox defines other constructors, so it does not automatically have default constructor
MessageBox is designed to be used as a static class - see http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx
You can make your class static using:
static class myclass {}
System.Windows.Forms.MessageBox has no default (empty) constructor.
A constructor can be hidden by setting its accessibility to something other than public.
The class' design declares that you can't use it as an object.
It only has static methods that can be used without instantiating an object of that class.
In case 1, MessageBox is a static class, it has no constructors (update - it has a private constructor says reflector but the OP gave a misleading/incorrect compiler error message.) Static classes are defined like this:
public static class MessageBox { }
A static class can only have static methods, and as such is not meant to be instantiated.
In case 2, MyClass is not a static class, and the compiler generates a default constructor for you if you don't define any constructors.
UPDATE: to all downvoters: go compile up a project with a static class and examine it in reflector - it decompiles without the static keyword becuase there is no MSIL or metadata for a static class; the compiler (in .net 2.0 or later) generates an abstract sealed class with no constructors. The keyword "static" is just syntactic sugar. Additionally, in 1.0/1.1 of .NET (when MessageBox was created,) the static keyword did not exist for classes and the sealed/private ctor was the accepted pattern.

Why keyword 'this' cannot be used in a static method?

Why can't the keyword this be used in a static method? I am wondering why C# defines this constraint. What benefits can be gained by this constraint?
[Update]:
Actually, this is a question I got in an interview.
I do know the usage of 'static' and 'this', based on all your response, I guess I know a little of why the two can not be used together. That is, for static method is used to changed state or do something in a type level, but when you need to use 'this' means you want to change the state or do something in a instance level. In order to differentiate the state change of a type and the state change of an instance, then c# donot allow use 'this' in a static method. Am I right?
Because this points to an instance of the class, in the static method you don't have an instance.
The this keyword refers to the current instance of the class. Static member functions do not have a this pointer
You'll notice the definition of a static member is
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object
Which is why this has nothing to point to.
this is an instance of the current object. With a static method, there is no current object, and as such, this doesn't exist. It's not really a constraint, but the entire point of a method being static.
this refers to the current instance of a class and can therefore be used only in instance methods. Static methods act on class level, where there are no instances. Hence, no this.
this refers to the current instance of the object. A static method is a method on the class. It is not an instance method and therefore using this inside a static method is meaningless.
I'm pretty sure this isn't limited to C# and it isn't a constraint, it's a logical situation. As #Yuriy correctly states, this refers to the current instance of a class, i.e. you've used new (or DI) to instantiate the class (created an instance of) and you need some way internally to refer to that instance, i.e. this object. A static method is called without instantiating the class, there is, in effect, no object created and as such you can't access properties of which this is one.
By static methods you can write:
MyClass.static_method();
which there is nothing to do with any object instance (so you don't need this keyword).
Because static_method() works and doesn't need object instances for its job. static_method() doesn't know which object instance do you have, but it can change the behavior
of all object instances:
MyClass a = new MyClass();
MyClass b = new MyClass();
MyClass.static_method("PRINTER");
a.display(); //print something
b.display(); //print something
MyClass.static_method("MONITOR");
a.display(); //display something on monitor
b.display(); //display something on monitor
In this case, static_method() changes the behavior of display() method in all object instances of MyClass.
The keyword this refers to the instance of the object. In the static context there is not specific instance to reference.
The this keyword can be used in a method marked as static. The syntax is used to define extension methods in C#. This feature has been available since C# 3.0, released in 2007 (Wikipedia)
In the normal usage, this refers to the instance, static says that there is no instance (and therefore no this). The fact that you can't use them together (aside from special exceptions like extension methods) follows naturally from understanding what this and static are, conceptually.
this is used to refer to the parent object of a variable or method. When you declare static on a method the method can be called without needing to instantiate an object of the class. Therefore the this keyword is not allowed because your static method is not associated with any objects.
'this' refers to an instance of a class. Static is initialized without instantiation and hence the static method cannot refer to an 'instance' that is not created.
The short answer for you will be: this refers to an instance of a class which is non existing in a static scope.
But please, look for a good book/class and try to understand basic object oriented concepts before going further on any object oriented programming language.
I am not sure if this helps your problem, but I believe these two code snippets are equivalent:
MyStaticClass.foo();
and simply
foo();
will both call the foo() method in the MyStaticClass class, assuming you call foo() from inside MyStaticClass
Edit - The easiest way to remember the difference between a static class and a non-static class is to think of something like the Math class in java. You can call Math.abs(x); to get the absolute value of x, and it does not really make sense to instantiate a Math object, which is why Math is a static class.
Another, more literal, take on your question:
The 'this' keyword can't be used in a static method to avoid confusion with its usage in instance methods where it is the symbol to access the pointer (reference) to the instance passed automatically as a hidden parameter to the method.
If not by that you could possibly define a local variable called 'this' in your static method, but that would be unrelated to the 'this' keyword referenced instance in the instance methods.
Below is an example with two equivalent methods, one static the other an instance method.
Both method calls will pass a single parameter to the methods executing code that will do the same thing (print the object's string representation on the console) and return.
public class Someclass {
void SomeInstanceMethod()
{ System.Console.WriteLine(this.ToString()); }
void static SomeStaticMethod(Someclass _this)
{ System.Console.WriteLine(_this.ToString()); }
public void static Main()
{
Someclass instance = new Someclass();
instance.SomeInstanceMethod();
SomeStaticMethod(instance);
}
}

Public constructor and static constructor

I am reading a code in C# that uses two constructors. One is static and the other is public. What is the difference between these two constructors? And for what we have to use static constructors?
static and public are orthogonal concepts (i.e. they don’t have anything to do with each other).
public simply means that users of the class can call that constructor (as opposed to, say, private).
static means that the method (in this case the constructor) belongs not to an instance of a class but to the “class itself”. In particular, a static constructor is called once, automatically, when the class is used for the first time.
Furthermore, a static constructor cannot be made public or private since it cannot be called manually; it’s only called by the .NET runtime itself – so marking it as public wouldn’t be meaningful.
Static constructor runs just once, before your class is instantiated. It's used if you want something to happen just once. A nice example would be a Bus class (similar to something they explain in MSDN article):
public class Bus
{
public static int busNo = 0;
static Bus()
{
Console.WriteLine("Woey, it's a new day! Drivers are starting to work.");
}
public Bus()
{
busNo++;
Console.WriteLine("Bus #{0} goes from the depot.", busNo);
}
}
class Program
{
static void Main(string[] args)
{
Bus busOne = new Bus();
Bus busTwo = new Bus();
}
// Output:
// Woey, it's a new day! Drivers are starting to work.
// Bus #1 goes from the depot.
// Bus #2 goes from the depot.
}
Static Constructor... It is guaranteed to be called "once" througout the life of the application/app Domain. It can contain statements that you want to be executed only once.
Public Constructor... Since we can not add access modifiers to a static constructor, a public constructor means you are talking about an instance constructor. If an instance constructor is public then the outside world can create its instances.
Other options are Internal ( can be called from within the library), Private ( from within the class only).
Static constructor called only the first instance of the class created but the public constructor called every time that instance of the class is created.
Static Constructor
A constructor declared using a static modifier is a static constructor.
A static constructor is used to initialize static data or to perform a
particular action that needs to be performed only once in the life cycle of
class. A static constructor is the first block of code to execute in class.
Static constructor executes one and only one time in the life cycle of
class. It is called automatically. The static constructor does not take
any parameters. It has no access to specifiers. It is not called
directly.
Instance or Public Constructor
Instance constructor is used to initialize instance data. Instance
constructor is called every time when the object of the class is created. It
is called explicitly. Instance constructor takes parameters. It has
access specifiers.
My source: Static Constructor Vs Instance Constructor in C#

When is a static constructor called in C#?

When I have class containing a static constructor, is that constructor called when the assembly containing the class is first loaded or when the first reference to that class is hit?
When the class is accessed for the first time.
Static Constructors (C# Programming Guide)
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
It's not quite as simple as you might expect despite straightforward documentation. Jon Skeet's article http://csharpindepth.com/Articles/General/Beforefieldinit.aspx goes into this question in details.
Summary:
Static constructor is guaranteed to be executed immediately before the first reference to a member of that class - either creation of instance or own static method/property of class.
Note that static initilaizers (if there is no static constructor) guaranteed to be executed any time before first reference to particular field.
The static constructor is called before you use anything in the class, but exactly when that happens is up to the implementation.
It's guaranteed to be called before the first static member is accessed and before the first instance is created. If the class is never used, the static constructor is not guaranteed to be called at all.
In case static method is called from parent class, static constructor will not be called, althogh it is explicitly specified. Here is an example b constructor is not called if b.methoda() is called.
static void Main(string[] args)
{
b.methoda();
}
class a
{
public static void methoda()
{
//using initialized method data
}
}
class b : a
{
static b()
{
//some initialization
}
}
There seems to be a gotcha with static constructors that is answered elsewhere but took a while to digest into a simple explanation. All the docs and explanations claim the static constructor/intializers are "guaranteed" to run before the first class is instantiated or the first static field is referenced. The gotcha comes in when you try to put a static singleton in the class that creates an instance of itself (chicken/egg). In this case the static constructor ends up being called after the instance constructor - and in my case the instance constructor contained code that relied on some static data.
Static constructor called after instance constructor?
Static constructor can run after the non-static constructor. Is this a compiler bug?
(the answer for me was to put the singleton in a separate class or manually initialize the static data in the instance constructor before it is required)

Categories

Resources