I am new to C# programming.
Please help me.
I created a class Tester:
class Tester
{
public int a = 5;
public int b = a;
}
Question 1 : Why am I not able to use this variable a for initializing the variable b.
Question 2: If I changed the variables to static then it works fine. Why is there a difference?
class Tester
{
public static int a = 5;
public static int b = a;
}
Question 3 : In previous example if I swap the sequence of variable then it works fine why because a is declaring after b . How can it initialize a?
class Tester
{
public static int b = a; // 0
public static int a = 5; // 5
}
There are some icky initialization order issues when you use fields initializers. A simple example would be:
class Test {
int a = b;
int b;
public Test() {
b = 1;
}
}
What will be the value of a? If you use the constructor-initializes-object rule then a will be 1. That however not the way it works under the hood, a would be 0 if the syntax where valid. A side-effect of the way field initializers are implemented, their code is injected into the constructor before the code in the body of the constructor. This problem gets a lot more convoluted when the class inherits base classes that have constructors.
This is too ugly, the C# language designers solved this by simply forbidding this kind of code. The rule is that you cannot reference this in a field initializer, that will create a reference to an object whose class constructor hasn't finished executing.
The rule is relaxed for static fields, there is no this reference and the CLR provides decent guarantees for class initializer execution order. That however doesn't avoid ambiguity, it is an exercise to guess what the field values will be in this example:
class Test {
static int a = b + 1;
static int b = a + 1;
}
Try it and see if you can make sense of the result. It is otherwise well-defined.
Answer1: You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that variable "a" will be initialized before "b", so the above line might throw a NullReferenceException.
Answer2: It works fine with static because static are initialize before other variables and their references are not changed.
Please let me know if it helps.
As Anirudh said. You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that a will be initialized before b.
You can use constructor for this.
class Tester
{
public int a=5;
public int b;
public Tester()//constructor
{
b=a;
}
}
or
class Tester
{
public static int a = 5;
public static int b;
public Tester()//constructor
{
b = a;
}
}
Related
This question already has answers here:
Why doesn't C# support local static variables like C does? [closed]
(13 answers)
Closed 3 years ago.
I came to know that,
From MSDN:
C# does not support static local variables (variables that are declared in method scope).
And here:
The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.
That is, local variables are not allowed as static inside a method.
Therefore, the below code will not compile
public class Base1
{
public int getHighscoreString()
{
int highscore = Int32.MinValue;
static int max = 10; // It is not allowed here.
if(max>highscore)
highscore = max;
return highscore;
}
}
But, we can always do the same functionality by
public class Base1
{
static int max = 10;
public int getHighscoreString()
{
int highscore = Int32.MinValue;
if(max>highscore)
highscore = max;
return highscore;
}
}
So, is it a design decision that static variable can not be used as local variable inside a method or any reason behind it?
A static variable is a variable that lives beyond the instances of the class in which is declared, in the sense that to get or set its value you have to call its class type and not its instances. This happens because a reference to the memory address where the static variable lives is kept regardless of the construction or disposal of instances of that class. Say you have a Zoo class:
public class Zoo
{
public static int counter;
public string Name;
public void AddAnimal(string name)
{
Name = name;
counter++;
}
}
The counter increases every time you add an animal to the zoo, and you can get the total anytime by calling
Zoo myZoo = new Zoo()
myZoo.AddAnimal(“tiger”);
Zoo.counter; // 1
myZoo.counter // wrong!
Apart from myZoo.counter being wrong, the main thing to notice is that even if we dispose of the myZoo instance, the counter field will always keep the total of the animals in the zoo!
On the contrary, variables declared in a method are immediately disposed after method execution and therefore you cannot reference them outside of that method because the memory address where the variable “lived” is not available anymore.
I hope this clarifies the matter a little more. Cheers!
I am a bit confused about how public variables work inside a class.
I know that public variables can be accessed without calling the class, whereas private ones cannot.
If you have multiple instances of the same class and in each you give a different value to a public variable then i assume each class instance would have its own unique version of the variable each with a different value.
My confusion is this
What happens if you change the value of the public variable without calling a new instance of the class?
Would all future new instances of the class start with that variable set to whatever you set it to without first calling the class? if not then what happens?
I think you somehow mixed up public variables and static variables. The below statement:
public variables can be accessed without calling the class
Is utterly and plainly wrong for non static variables, might they be private or public.
If you change public variable of a class instance, it will change only that instance, having no effect whatsoever on other existing instances or future instances.
Static variables on the other hand can indeed be called without an instance of the class and changing them has "global" effect, not related to class instance.
(If you have any specific code you worked with and need further guidance please post it)
In languages like C#, you can´t do that.
Accessing any (non-static) variable of a class itself instead of a instance of it
would result in a compiler error.
Perhaps some sample code will help; private variables cannot be accessed so I'm guessing your terminology is getting mixed up. In the below sample, the PublicStaticInt property is declared as static; simply put, that means there is only one copy of it in your AppDomain. Every instance of ExampleClass that is created references that same copy of it. The PublicInt property is an instance property; that means that every instance of ExampleClass has its own copy of that piece of data.
public class ExampleClass
{
public static int PublicStaticInt { get; set; }
public int PublicInt { get; set; }
}
private static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
var example = new ExampleClass();
Console.WriteLine("PublicStaticInt = " + ExampleClass.PublicStaticInt.ToString() + ", PublicInt = " + example.PublicInt);
ExampleClass.PublicStaticInt++;
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
When you create a new instance of same class then every instance has its own values for each data members. for example
class A
{
public int a;
public int b;
public A()
{
a=0;
b=0;
}
}
when i create instance of class A like this
A a11 =new A();
A b11 = new A();
Now if I change the value of a11 it will never change the value of b11 and if I change the value of b11 it will never change the value of a11.
Would all future new instances of the class start with that variable set to whatever you set it to without first calling the class? if not then what happens?
No they will set to values that you have set in the constructor of the class. In this case it will set values of a and b equal to zero for every instance of class because it is done the constructor.
Consider the code below. Fields i and j are initialized before m and n. We know that the parent object is created before the child object, but in my program the compiler is allocating and initializing memory for the child class' member variables before the base class'. Why is that?
class X
{
private int m = 0;
private int n = 90;
public X() { }
}
class Y:X
{
private int i = 8;
private int j = 6;
public Y()
{ }
public static void Main(string []args)
{
Y y1 = new Y();
}
}
This is explained in Eric Lippert's blog:
[...] an initialized readonly field is always observed in its initialized state, and we cannot make that guarantee unless we run all the initializers first, and then all of the constructor bodies.
Not sure why readonly is mentioned here, but for example, this ensures that the following scenarios, albeit being stupid, work:
1.
class Base
{
public Base()
{
if (this is Derived) (this as Derived).Go();
}
}
class Derived : Base
{
X x = new X();
public void Go()
{
x.DoSomething(); // !
}
}
2.
class Base
{
public Base()
{
Go();
}
public virtual Go() {}
}
class Derived : Base
{
X x = new X();
public override void Go()
{
x.DoSomething(); // !
}
}
This order is explicitly stated in C# Language Specification (17.10.2):
[...] 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.
This is one of those rare places where an understanding of procedural methodology makes object-oriented methodology easier to understand. Even though you're working OOP, the compiler still adheres to procedural logic - working start to finish.
A simple example is when the compiler hits private int n = 90. First it allocates space for an integer value, then an identifier to access it as an integer, then assigns it the value of 90. It can't assign the value until it both has the space to stick it AND knows how to access it, nor can it access non-existent space.
In this instance, your derived class Y is built atop the base class X, similar to how the variable n is built atop the "class" integer in the example above. This is triggered by the declaration class Y:X - the compiler can't even start building Y until it understands how to build X.
Child construction code must be allowed to call functions on the parent, which can't work unless the parent is already fully-constructed.
However, the objects share the same memory block. So all the memory is allocated in one go, then the classes are initialized working up the class hierarchy.
I have searched about static variables in C#, but I am still not getting what its use is. Also, if I try to declare the variable inside the method it will not give me the permission to do this. Why?
I have seen some examples about the static variables. I've seen that we don't need to create an instance of the class to access the variable, but that is not enough to understand what its use is and when to use it.
Second thing
class Book
{
public static int myInt = 0;
}
public class Exercise
{
static void Main()
{
Book book = new Book();
Console.WriteLine(book.myInt); // Shows error. Why does it show me error?
// Can't I access the static variable
// by making the instance of a class?
Console.ReadKey();
}
}
A static variable shares the value of it among all instances of the class.
Example without declaring it static:
public class Variable
{
public int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}
public class Exercise
{
static void Main()
{
Variable var1 = new Variable();
var1.test();
Variable var2 = new Variable();
var2.test();
Console.ReadKey();
}
}
Explanation: If you look at the above example, I just declare the int variable. When I run this code the output will be 10 and 10. Its simple.
Now let's look at the static variable here; I am declaring the variable as a static.
Example with static variable:
public class Variable
{
public static int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}
public class Exercise
{
static void Main()
{
Variable var1 = new Variable();
var1.test();
Variable var2 = new Variable();
var2.test();
Console.ReadKey();
}
}
Now when I run above code, the output will be 10 and 15. So the static variable value is shared among all instances of that class.
C# doesn't support static local variables (that is, variables that are declared in method scope).
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members#static-members
You can declare static fields (class members) though.
Reasoning: Static field is a state, shared with all instances of particular type. Hence, the scope of the static field is entire type. That's why you can't declare static instance variable (within a method) - method is a scope itself, and items declared in a method must be inaccessible over the method's border.
static variables are used when only one copy of the variable is required. so if you declare variable inside the method there is no use of such variable it's become local to function only..
example of static is
class myclass
{
public static int a = 0;
}
Variables declared static are commonly shared across all instances of a class.
Variables declared static are commonly shared across all instances of a class. When you create multiple instances of VariableTest class This variable permanent is shared across all of them. Thus, at any given point of time, there will be only one string value contained in the permanent variable.
Since there is only one copy of the variable available for all instances, the code this.permament will result in compilation errors because it can be recalled that this.variablename refers to the instance variable name. Thus, static variables are to be accessed directly, as indicated in the code.
Some "real world" examples for static variables:
building a class where you can reach hardcoded values for your application. Similar to an enumeration, but with more flexibility on the datatype.
public static class Enemies
{
public readonly static Guid Orc = new Guid("{937C145C-D432-4DE2-A08D-6AC6E7F2732C}");
}
The widely known singleton, this allows to control to have exactly one instance of a class. This is very useful if you want access to it in your whole application, but not pass it to every class just to allow this class to use it.
public sealed class TextureManager
{
private TextureManager() {}
public string LoadTexture(string aPath);
private static TextureManager sInstance = new TextureManager();
public static TextureManager Instance
{
get { return sInstance; }
}
}
and this is how you would call the texturemanager
TextureManager.Instance.LoadTexture("myImage.png");
About your last question:
You are refering to compiler error CS0176. I tried to find more infor about that, but could only find what the msdn had to say about it:
A static method, field, property, or event is callable on a class even
when no instance of the class has been created. If any instances of
the class are created, they cannot be used to access the static
member. Only one copy of static fields and events exists, and static
methods and properties can only access static fields and static
events.
Static variables are used when only one copy of it is required. Let me explain this with an example:
class circle
{
public float _PI =3.14F;
public int Radius;
public funtionArea(int radius)
{
return this.radius * this._PI
}
}
class program
{
public static void main()
{
Circle c1 = new Cirle();
float area1 = c1.functionRaduis(5);
Circle c2 = new Cirle();
float area2 = c1.functionRaduis(6);
}
}
Now here we have created 2 instances for our class circle , i.e 2 sets of copies of _PI along with other variables are created. So say if we have lots of instances of this class multiple copies of _PI will be created occupying memory. So in such cases it is better to make such variables like _PI static and operate on them.
class circle
{
static float _PI =3.14F;
public int Radius;
public funtionArea(int radius)
{
return this.radius * Circle._PI
}
}
class program
{
public static void main()
{
Circle c1 = new Cirle();
float area1 = c1.functionRaduis(5);
Circle c2 = new Cirle();
float area2 = c1.functionRaduis(6);
}
}
Now no matter how many instances are made for the class circle , only one copy exists of variable _PI saving our memory.
Static classes don't require you to create an object of that class/instantiate them, you can prefix the C# keyword static in front of the class name, to make it static.
Remember: we're not instantiating the Console class, String class, Array Class.
class Book
{
public static int myInt = 0;
}
public class Exercise
{
static void Main()
{
Book book = new Book();
//Use the class name directly to call the property myInt,
//don't use the object to access the value of property myInt
Console.WriteLine(Book.myInt);
Console.ReadKey();
}
}
The data members and function members that operate on the instance of the type
are called instance members. The int’s ToString method (for example) are examples of instance members. By default, members are instance members.
Data members and function members that don’t operate on the instance of the type, but rather on the type itself, must be marked as static. The Test.Main and Console.WriteLine methods are static methods. The Console class is actually a static class, which means all its members are static. You never actually create instances of a Console—one console is shared across the whole application.
In response to the "when to use it?" question:
I often use a static (class) variable to assign a unique instance ID to every instance of a class. I use the same code in every class, it is very simple:
//Instance ID ----------------------------------------
// Class variable holding the last assigned IID
private static int xID = 0;
// Lock to make threadsafe (can omit if single-threaded)
private static object xIDLock = new object();
// Private class method to return the next unique IID
// - accessible only to instances of the class
private static int NextIID()
{
lock (xIDLock) { return ++xID; }
}
// Public class method to report the last IID used
// (i.e. the number of instances created)
public static int LastIID() { return xID; }
// Instance readonly property containing the unique instance ID
public readonly int IID = NextIID();
//-----------------------------------------------------
This illustrates a couple of points about static variables and methods:
Static variables and methods are associated with the class, not any specific instance of the class.
A static method can be called in the constructor of an instance - in this case, the static method NextIID is used to initialize the readonly property IID, which is the unique ID for this instance.
I find this useful because I develop applications in which swarms of objects are used and it is good to be able to track how many have been created, and to track/query individual instances.
I also use class variables to track things like totals and averages of properties of the instances which can be reported in real time. I think the class is a good place to keep summary information about all the instances of the class.
Try calling it directly with class name Book.myInt
On comparison with session variables, static variables will have same value for all users considering i am using an application that is deployed in server. If two users accessing the same page of an application then the static variable will hold the latest value and the same value will be supplied to both the users unlike session variables that is different for each user. So, if you want something common and same for all users including the values that are supposed to be used along the application code then only use static.
You don't need to instantiate an object, because yau are going to use
a static variable:
Console.WriteLine(Book.myInt);
Static variable retains it's previous value until the program exit. Static is used by calling directly class_Name.Method() or class_Name.Property. No object reference is needed. The most popular use of static is C#'s Math class.
Math.Sin(), Math.Cos(), Math.Sqrt().
I'll try to keep this simple.
class MyClass {
private int x = 3;
}
vs.
class MyClass {
private int x;
public MyClass() {
x = 3;
}
}
What's the difference between the two and how do these differences come into play?
Thanks in advance.
class MyClass {
private int x = 3;
}
is same as
class MyClass {
private int x;
MyClass() { // default constructor based on the class access modifier
x = 3;
}
}
These are both the same
But if x were a static variable, they would be different.
Nothing at all. Variable's are set when a constructor is called, you can see this by adding the line MyClass temp = new MyClass() and stepping into it with the debugger, the debugger will go to the line private int x = 3; first.
Initialization of fields are done before constructor is called. But for your example they are same
In your example you actually have instance variable, not the class variable.
Difference comes in the moment when you add new constructor MyClass(Object argument) and forget to set x directly and forget to call original no-arg constructor as well. Making it final, if applicable, will of course force you to remember to set value somewhere.
In the case of class variable things get much more interesting, just change x to static and add following main method to the MyClass and observe results.
public static void main(String ... args) {
MyClass y = null;
System.out.println(y.x);
System.out.println(MyClass.x);
new MyClass();
System.out.println(MyClass.x);
}
As others has mentioned they both are equivalent. The main difference is the readability, duplicity and maintainability of the code. If we expand the given example to have more than one constructor you'll start to notice differences. If the value of x is not to depend on the constructor I'd recommend to initialize the field variable else set the value in the constructors. This will somewhat increase the readability and maintainability of the code and remove duplicated code (in the case were several constructors are to initiate the variable with the same value).