Assining values to class variables - c#

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).

Related

Public variable inside a class

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.

Why child class variable initialize before parent class member variable

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.

About Constructor and methods in c#

What is the reason for initialization using constructor instead of method.
Code 1:
class A {
int x, y;
public A() {
x = 10;
y = 4;
}
}
Code 2:
class A {
int x, y;
public fun() {
x = 10;
y = 4;
}
}
From above, what is the difference between Code 1 and Code 2.
If any one know the answer please clear my doubt.?
It is guaranteed that constructor will get called when object is created but in case of method it is your control when to call. If you initialize values in method instead of constructor, there may be side effect if you call the method at wrong time.
Therefore it is always good practice to initialize the values in constructor instead of methods and that is the purpose of constructor.
First assignment occurs when instance is created. Second assignment occurs when you will execute the fun() method.
BTW you can call fun() method in constructor.
A constructor ensures that the object is properly instantiated. There's not guarantee that the caller will call the method to manually instantiate the object.
the constructor is called to create the instance of your class and does not rely on calls, unlike the method
When using code 1, A a = new A(); will init x and y.
When using code 2, you need A a = new A(); and a.fun(); to init x and y.
Init of your variables should be placed within a method if you wanna use this method also for additional inits sometime later.
btw fun is not an adequate name for a method.
A constructor is implicitly called when an object is created. In second case, the method is an instance level method.. You will have to create an object of type A and then "change" the values of x and y... The defualt constructor will assign default value (0) to your int variables...
Constructor used as initializer , because of it provide the functionality to initializing the object to memory or when a object is created at that time constructor will call first. If you don't initialize any value separately and you want to use some variable in your result then you can use constructor as initializer.
Why constructor use in coding? Bcz it have the nature to initialize some thing before of creation of Object.
I think you got my point. happy learning. :)
Thanks
Technically, you can hide constructor and use factory method pattern:
class A {
int x, y;
// Hidden constructor
protected A() {
x = 10;
y = 4;
}
// Factory method to create A class instances
public static A Create() {
...
A result = new A();
...
return result;
}
}
In your example factory method is an overshoot, but it could be helpful
when implementing singleton, strategy patterns etc.

How variable stored in class and their flow of execution?

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;
}
}

C# object initialization options

Doesn't object initialization outside of a constructor break encapsulation ?
Given:
class MyClass
{
public string _aString;
}
Shouldn't the _aString member be private and instantiated via a call to the constructor (constructor omitted here):
MyClass test = new MyClass("test");
Instead of the alternate method of object initialization:
MyClass test = new MyClass { _aString = "Test" };
"Doesn't object initialization outside of a constructor break encapsulation ?"
Well, no. As you rightly pointed out you can only initialize properties that are already accessible in your current scope. (public, internal etc)
This kind of Intialization is really just some syntactic sugar around construction of a class and assigning values to properties, It is very useful for Anonymous classes and Linq select clauses.
It is usually considered bad practice to expose public fields... it may be acceptable in some cases, for instance if the field is marked as readonly (which means it must be set in the constructor). Instead, you should make this field private and expose it through a property, which may or may not be readonly, depending on its purpose :
class MyClass
{
private string _aString;
public string AString
{
get { return _aString; }
// uncomment to make the property writable
//set { _aString = value; }
}
}
If you consider Properties as getters and setters, I don't believe it will break encapsulation. But you should notice that you didn't use a Property, you have used an instance variable. In fact, I don't believe it will work like your example. Check this one:
class MyClass {
private string aString;
public string AString {
get { return aString; }
set {aString = value; }
}
}
MyClass test = new MyClass {
AString = "test"
};
In this case, you are accessing the private field through it's accessor. It's just like using a parameterless constructor and setting the value later.
It depends on the purpose of the variable. If the programmer should only be able to set the variable at initialization, but then not have access to it after that, then I would go with the private variable. If you want the class user to be able to set / read the variable at any time, then make it public.
When you have
public string _aString;
it really does not matter when you initialize this value since this is already exposed. So, when we want to talk about initialization we should move this string into property. Than talkin about encapsutlation makes sense.
So, imagine we have some string. There are mosly two approaches to initializatnion. One is to do it inside constructor, second is lazy initialization (initialize when some request this data).
yes, initialize via the constructor, and add properties to allow (or not) access to the data.
class MyClass {
private string _aString;
string MyProperty {
get { return this._aString; }
// you can make this private or protected
set { this._aString = value; }
}
}
If you're asking if the new object initialization shorthand breaks encapsulation, then the answer is no. You can only set publicly scoped members with the new method.
MyClass test = new MyClass { _aString = "Test" };
is the same as
MyClass test = new MyClass();
test._aString = "Test";
To show an object public in a C# class does not break "encapsulation" from a point of view of "Object-oriented programming".
From a point of view of a "good practise" it not a good thing, use Properties because it allows to external code to use this class if you change the behaviour of updating this value (checking, ...).

Categories