Thursday, January 26, 2012

Introduction to C sharp

What is OOP?

OOP is a design philosophy. It stands for Object Oriented Programming. Object-Oriented Programming (OOP) uses a different set of programming languages than old procedural programming languages (C, Pascal, etc.). Everything in OOP is grouped as self sustainable "objects". Hence, you gain re-usability by means of four main object-oriented programming concepts.

What is a Class?

Much as a blueprint or architect's drawing defines the members, properties and methods. what an item or a building will look like once it has been constructed, a class defines what an object will look like when it is created. It defines, for example, what the methods will do and what the member variables will be.

Declaring a C# Class

Public class Bank
{
String BankName;
String BankAddress;
Int BankValue;
}
 
public class BankAccount:Bank
{
String DepositerName;
Int BankAccountNo;
Sring DepositerAddress;
String DepositerEmail;
String DepositerContact;
 
Static void Method(String[] args)
{
If(Int BankAccountNo>=200)
{
Console.WriteLine(“Not a valid BankAccount”);
}
 
}
 
}

 

What is an Object?

An object is an instance of a class. A
An object is a self-contained piece of functionality that can be easily used, and re-used as the building blocks for a software application.
Objects consist of data variables and functions (called methods) that can be accessed and called on the object to perform tasks. These are collectively referred to as members.
BankAccount  BA1 = new BankAccount(); // this is the way of creating an object from a class.
BA1.DepositerName
BA1.MainMethod();

BankAccount B2 = New BankAccount();

Advantages of using classes and objects

1.      Maintenance of code by introducing modularity
2.      Encapsulation of internal complexities in code from end users
3.      Reusability
4.      Support for a single inheritance to implement multiple methods

Inheritance

One of the strengths of object-oriented programming is inheritance. This feature allows you to create a new class that is based on an old class. Ability of a new class to be created, from an existing class by extending it, is called inheritance.
public class Exception
{
}


public class IOException : Exception
{
//here Exception is the base class and IOException is a new class.
}
Constructors
Constructors are special methods in a class that allow control over the initialization of objects. The name of a constructor is same as the name of the class that contains it. There are two types of constructors instance constructor and static constructor.
What is constructor?
  • Constructor is used to initialize an object (instance) of a class.
  • Constructor is a like a method without any return type.
  • Constructor has same name as class name.
  • Constructor follows the access scope (Can be private, protected, public, Internal and external).
  • Constructor can be overloaded.

 

Static Constructors

This is a new concept introduced in C#. By new here, I mean that it was not available for the C++ developers. This is a special constructor and gets called before the first object is created of the class. The time of execution cannot be determined, but it is definitely before the first object creation - could be at the time of loading the assembly.
public class myClass
{
    static myClass()
    {
        // Initialization code goes here.

        // Can only access static members here.

    }
    // Other class methods goes here

}

Notes for Static Constructors:
  1. There can be only one static constructor in the class.
  2. The static constructor should be without parameters.
  3. It can only access the static members of the class.
  4. There should be no access modifier in static constructor definition.
Firstly, the call to the static method is made by the CLR and not by the object, so we do not need to have the access modifier to it.
Secondly, it is going to be called by CLR, who can pass the parameters to it, if required. So we cannot have parameterized static constructor.
Thirdly, non-static members in the class are specific to the object instance. So static constructor, if allowed to work on non-static members, will reflect the changes in all the object instances, which is impractical so static constructor can access only static members of the class.
Fourthly, overloading needs the two methods to be different in terms of methods definition, which you cannot do with Static Constructors, so you can have at the most one static constructor in the class.
public class myClass
{
    static myClass()
    {
        // Initialization code goes here.

        // Can only access static members here.

    }
    public myClass()
    {
        // Code for the First myDerivedClass Constructor.

    }

    // Other class methods goes here

}

This is perfectly valid, though doesn't seem to be in accordance with overloading concepts. But why  Because the time of execution of the two methods are different. One is at the time of loading the assembly and one is at the time of object creation.

Destructors

In order to produce high performance scalable applications, it is important to use your resources in an optimized manner. One tip is that use your resource as late as you can and free it at the earliest after your use.
As we all know, Destructors are used to destruct instances of classes. When we are using destructors in C#, we have to keep in mind the following things:
  • A class can only have one destructor.
  • Destructors cannot be inherited or overloaded.
  • Destructors cannot be called. They are invoked automatically.
  • A destructor does not take modifiers or have parameters.
The following is a declaration of a destructor for the class MyClass:
~ MyClass() 
{
   // Cleaning up code goes here
 
}

The programmer has no control on when the destructor is going to be executed because this is determined by the Garbage Collector. The garbage collector checks for objects that are no longer being used by the application. It considers these objects eligible for destruction and reclaims their memory. Destructors are also called when the program exits. When a destructor executes what is happening behind the scenes is that the destructor implicitly calls the Object.Finalize method on the object's base class. Therefore, the preceding destructor code is implicitly translated to:
protected override void Finalize()
{
   try
   {
      // Cleaning up .
 
   }
   finally
   {
      base.Finalize();
   }
}
Now, let us look at an example of how destructors are called. We have three classes A, B and C. B is derived from A, and C is derived from B. Each class has their own constructors and destructors. In the main of the class App, we create an object of C.

class A
{
 public A()
 {
  Console.WriteLine("Creating A");
 }
 ~A()
 {
  Console.WriteLine("Destroying A");
 }
}
 
class B:A
{
 public B()
 {
  Console.WriteLine("Creating B");
 }
 ~B()
 {
  Console.WriteLine("Destroying B");
 }
 
}
class C:B
{
 public C()
 {
  Console.WriteLine("Creating C");
 }
 
 ~C()
 {
  Console.WriteLine("Destroying C");
 }
}
class App
{
 public static void Main()
 {

C c=new C();
  Console.WriteLine("Object Created ");
  Console.WriteLine("Press enter to Destroy it");
  Console.ReadLine();
  c=null;
  //GC.Collect();
 
  Console.Read();
}
 
}

Calling the garbage collector

You can force the garbage collector to do clean up by calling the GC.Collect method, but in most cases, this should be avoided because it may result in performance issues. In the above program, remove the comment on GC.Collect(). Compile and run it. Now, you can see the destructors being executed in the console itself.

What is Encapsulation (or information hiding)?

The encapsulation is the inclusion within a program object of all the resources need for the object to function - basically, the methods and the data. In OOP the encapsulation is mainly achieved by creating classes, the classes expose public methods and properties. The class is kind of a container or capsule or a cell, which encapsulate the set of methods, attribute and properties to provide its indented functionalities to other classes. In that sense, encapsulation also allows a class to change its internal implementation without hurting the overall functioning of the system. That idea of encapsulation is to hide how a class does it but to allow requesting what to do.

What is an Abstract class?

Abstract classes, which declared with the abstract keyword, cannot be instantiated. It can only be used as a super-class for other classes that extend the abstract class. Abstract class is the concept and implementation gets completed when it is being realized by a subclass. In addition to this a class can inherit only from one abstract class (but a class may implement many interfaces) and must override all its abstract methods/ properties and may override virtual methods/ properties.
Abstract classes are ideal when implementing frameworks.

What is an Interface?

An interface is not a class. It is an entity that is defined by the word Interface. An interface has no implementation; it only has the signature or in other words, just the definition of the methods without the body. As one of the similarities to Abstract class, it is a contract that is used to define hierarchies for all subclasses or it defines specific set of methods and their arguments. The main difference between them is that a class can implement more than one interface but can only inherit from one abstract class. Since C# doesnt support multiple inheritance, interfaces are used to implement multiple inheritance.

Abstract Class and Interface

When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface.
When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared abstract. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes.

What is Polymorphisms?

Polymorphisms is a generic term that means 'many shapes'. More precisely Polymorphisms means the ability to request that the same operations be performed by a wide range of different types of things.
Polymorphism provides following features: 
  • It allows you to invoke methods of derived class through base class reference during runtime.
  • It has the ability for classes to provide different implementations of methods that are called through the same name.
Polymorphism is of two types: 
Compile time polymorphism/Overloading
Runtime polymorphism/Overriding
Compile Time Polymorphism
 
Compile time polymorphism is method and operators overloading. It is also called early binding.
 
In method overloading method performs the different task at the different input parameters.
Runtime Time Polymorphism
 
Runtime time polymorphism is done using inheritance and virtual functions. Method overriding is called runtime polymorphism. It is also called late binding.
 
When overriding a method, you change the behavior of the method for the derived class.  Overloading a method simply involves having another method with the same prototype.
Method overloading has nothing to do with inheritance or virtual methods.
Practical example of Method Overloading (Compile Time Polymorphism)
 
using System;
 
namespace method_overloading
{
    class Program
    {
        public class Print
        {
           
            public void display(string name)
            {
                Console.WriteLine("Your name is : " + name);
            }
 
            public void display(int age, float marks)
            {
                Console.WriteLine("Your age is : " + age);
                Console.WriteLine("Your marks are :" + marks);
            }
        }
       
        static void Main(string[] args)
        {
 
            Print obj = new Print();
            obj.display("George");
            obj.display(34, 76.50f);
            Console.ReadLine();
        }
    }
}
 
Note: In the code if you observe display method is called two times. Display method will work according to the number of parameters and type of parameters.

When and why to use method overloading
 
Use method overloading in situation where you want a class to be able to do something, but there is more than one possibility for what information is supplied to the method that carries out the task.
You should consider overloading a method when you for some reason need a couple of methods that take different parameters, but conceptually do the same thing.
Method Overloading showing many forms.
 
using System;
 
namespace method_overloading_polymorphism
{
    class Program
    {
        public class Shape
        {
            public void Area(float r)
            {
                float a = (float)3.14 * r;
                // here we have used funtion overload with 1 parameter.
                Console.WriteLine("Area of a circle: {0}",a);
            }
 
            public void Area(float l, float b)
            {
                float x = (float)l* b;
                // here we have used funtion overload with 2 parameters.
                Console.WriteLine("Area of a rectangle: {0}",x);
 
            }
 
            public void Area(float a, float b, float c)
            {
                float s = (float)(a*b*c)/2;
                // here we have used funtion overload with 3 parameters.
                Console.WriteLine("Area of a circle: {0}", s);
            }
        }
 
        static void Main(string[] args)
        {
            Shape ob = new Shape();
            ob.Area(2.0f);
            ob.Area(20.0f,30.0f);
            ob.Area(2.0f,3.0f,4.0f);
            Console.ReadLine();
        }
    }
}
 
Things to keep in mind while method overloading
  If you use overload for method, there are couple of restrictions that the compiler imposes.
  The rule is that overloads must be different in their signature, which means the name and the number and type of parameters.
 There is no limit to how many overload of a method you can have. You simply declare them in a class, just as if they were different methods that happened to have the same name.


Override

Use the override modifier to modify a method, a property, an indexer, or an event. An override method provides a new implementation of a member inherited from a base class. The method overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.
You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override. 
An overriding property declaration must specify the exact same access modifier, type, and name as the inherited property, and the overridden property must be virtual, abstract, or override.
From within the derived class that has an override method, you still can access the overridden base method that has the same name by using the base keyword. For example, if you have a virtual method MyMethod(), and an override method on a derived class, you can access the virtual method from the derived class by using the call:
base.MyMethod()
Compare this to the C++ way, where you use the scope resolution operator (::) and the base class name, for example:
My_Base_Class_Name::MyMethod()

Example

In this example, there is a base class, Square, and a derived class, Cube. Because the area of a cube is the sum of the areas of six squares, it is possible to calculate it by calling the Area() method on the base class.
// cs_override_keyword.cs
// Calling overriden methods from the base class
using System;
class TestClass 
{
   public class Square 
   {
      public double x;
 
      // Constructor:
      public Square(double x) 
      {
         this.x = x;
      }
 
      public virtual double Area() 
      {
         return x*x; 
      }
   }
 
   class Cube: Square 
   {
      // Constructor:
      public Cube(double x): base(x) 
      {
      }
 
      // Calling the Area base method:
      public override double Area() 
      {
         return (6*(base.Area())); 
      }
   }
 
   public static void Main()
   {
      double x = 5.2;
      Square s = new Square(x);
      Square c = new Cube(x);
      Console.WriteLine("Area of Square = {0:F2}", s.Area());
      Console.WriteLine("Area of Cube = {0:F2}", c.Area());
   }
}

Output

Area of Square = 27.04
Area of Cube = 162.24

Lesson 12: Structs

This lesson will teach you about the C# struct. Our objectives are as follows:
  • Understand the Purpose of structs.
  • Implement a struct.
  • Use a struct.

Creating a Custom struct Type

While the behavior of class and struct types are very different, their syntax is similar. You declare the type and its members with the primary visual difference being that a struct uses the keyword struct and a class uses the keyword class. The example in Listing 12-1 demonstrates how to define a custom struct. In this case, the struct is a Rectangle with Width and Height properties, similar to what you might use to represent a rectangular shape on a screen.
Listing 12-1. Defining a struct
/// <summary>
/// Custom struct type, representing a rectangular shape
/// </summary>
struct Rectangle
{
    /// <summary>
    /// Backing Store for Width
    /// </summary>
    private int m_width;
 
    /// <summary>
    /// Width of rectangle
    /// </summary>
    public int Width 
    {
        get
        {
            return m_width;
        }
        set
        {
            m_width = value;
        }
    }
 
    /// <summary>
    /// Backing store for Height
    /// </summary>
    private int m_height;
 
    /// <summary>
    /// Height of rectangle
    /// </summary>
    public int Height
    {
        get
        {
            return m_height;
        }
        set
        {
            m_height = value;
        }
    }
}
As you can see, the Rectangle struct in Listing 1-2 looks very much like a class with a couple properties, except that it uses the keyword struct, instead of the keyword class, to declare that Rectangle is a struct

Using a struct

To use a struct, instantiate the struct and use it just like a class.  Listing 12-2 shows how to instantiate the Rectangle struct and access its properties.
Listing 12-2. Using a Struct
using System;
 
/// <summary>
/// Example of declaring and using a struct
/// </summary>
class StructExample
{
    /// <summary>
    /// Entry point: execution starts here
    /// </summary>
    static void Main()
    {
        // instantiate a new Rectangle struct
        // where Width is set to 1 and Height is set to 3
        Rectangle rect1 = new Rectangle();
        rect1.Width = 1;
        rect1.Height = 3;
 
        // show the value of Width and Height for rect1
        Console.WriteLine("rect1:  {0}:{1}", rect1.Width, rect1.Height);
 
        Console.ReadKey();
    }
}
The code in the Main method of Listing 12-2 instantiates a new Rectangle struct and sets its Height and Width properties. The experience is similar to how a class can be used.  Here's the output:
rect1: 1:3
An alternate way of instantiating a struct and setting its properties is with an object initializer, shown below:
        // you can also use object initialization syntax
        Rectangle rect11 = new Rectangle
        {
            Width = 1,
            Height = 3
        };
Notice that the object initializer uses curly braces and sets properties via a comma-separated list of name/value pairs.

Overloading struct Constructors

The two previous examples of instantiating a struct, via constructor only and via object initializer, used the default (parameterless) constructor of the struct. The default constructor is implicitly defined by C# and you can't implement the default constructor yourself.  The default constructor initializes all struct fields to default values. i.e. integrals are 0, floating points are 0.0, and booleans are false. If you need custom constructor overloads, you can add new constructors, as long as they have one or more parameters. Listing 12-3 shows a customization of the Rectangle struct from Listing 12-1 that includes a constructor overload.
Listing 12-3: Overloading a struct Constructor
/// <summary>
/// Custom struct type, representing a rectangular shape
/// </summary>
struct Rectangle
{
    /// <summary>
    /// Backing Store for Width
    /// </summary>
    private int m_width;
 
    /// <summary>
    /// Width of rectangle
    /// </summary>
    public int Width 
    {
        get
        {
            return m_width;
        }
        set
        {
            m_width = value;
        }
    }
 
    /// <summary>
    /// Backing store for Height
    /// </summary>
    private int m_height;
 
    /// <summary>
    /// Height of rectangle
    /// </summary>
    public int Height
    {
        get
        {
            return m_height;
        }
        set
        {
            m_height = value;
        }
    }
 
    /// <summary>
    /// Instantiate rectangle struct with dimensions
    /// </summary>
    /// <param name="width">Width to make new rectangle</param>
    /// <param name="height">Height to make new rectangle</param>
    public Rectangle(int width, int height)
    {
        m_width = width;
        m_height = height;
    }
}
The highlighted portion of code in Listing 12-3 is a constructor overload. Constructors are named the same as their containing class, which is Rectangle in this case. This Rectangle constructor overload has two parameters, which it assigns to backing stores that are encapsulated by properties for calling code. Listing 12-4 shows an example of how you would use the constructor overload in Listing 12-3 to instantiate a new Rectangle.
Listing 12-4: Instantiating a struct Through a Constructor Overload
using System;
 
/// <summary>
/// Example of declaring and using a struct
/// </summary>
class StructExample
{
    /// <summary>
    /// Entry point: execution starts here
    /// </summary>
    static void Main()
    {
        // instantiate a new Rectangle struct
        // where Width is set to 5 and Height is set to 7
        Rectangle rect2 = new Rectangle(5, 7);
 
        // show the value of Width and Height for rect2
        Console.WriteLine("rect2:  {0}:{1}", rect2.Width, rect2.Height);
 
        Console.ReadKey();
    }
}
The code in the Main method of Listing 12-4 instantiates a Rectangle struct and displays the values set via the constructor overload. When instantiating rect2, the code passes the values 5 and 7 as arguments. From Listing 12-3, you can see that the Width of rect2 will be set to 5 and the Height of rect2 will be set to 7. Here's the output from Listing 12-4:
rect2: 5:7

Adding a Method to a struct

All of the examples so far showed how you can add properties and constructors to a struct, but you can also add methods to a struct. Defining a method in a struct is the same as defining a method in a class. Listing 12-5 shows the Rectangle struct with a method named Add.
Listing 12-5: Adding a Method to a struct
/// <summary>
/// Custom struct type, representing a rectangular shape
/// </summary>
struct Rectangle
{
    /// <summary>
    /// Backing Store for Width
    /// </summary>
    private int m_width;
 
    /// <summary>
    /// Width of rectangle
    /// </summary>
    public int Width 
    {
        get
        {
            return m_width;
        }
        set
        {
            m_width = value;
        }
    }
 
    /// <summary>
    /// Backing store for Height
    /// </summary>
    private int m_height;
 
    /// <summary>
    /// Height of rectangle
    /// </summary>
    public int Height
    {
        get
        {
            return m_height;
        }
        set
        {
            m_height = value;
        }
    }
 
    /// <summary>
    /// Instantiate rectangle struct with dimensions
    /// </summary>
    /// <param name="width">Width to make new rectangle</param>
    /// <param name="height">Height to make new rectangle</param>
    public Rectangle(int width, int height)
    {
        m_width = width;
        m_height = height;
    }
 
    /// <summary>
    /// Increase the size of this rectangle by the size of the specified rectangle
    /// </summary>
    /// <param name="rect">Rectangle that will be added to this rectangle</param>
    /// <returns>New rectangle created by adding rect to this rectangle</returns>
    public Rectangle Add(Rectangle rect)
    {
        // create instance of rectangle struct with default constructor
        Rectangle newRect = new Rectangle();
 
        // add matching axes and assign to new Point struct
        newRect.Width = Width + rect.Width; 
        newRect.Height = Height + rect.Height;
 
        // return new point struct
        return newRect;
    }
}
The highlighted code in Listing 12-5 is a method named Add. It might or might not make sense to add two Rectangle structs together, but the example demonstrates how to define a method in a struct. In this case, the Add method will increase the Height and Width of the current Rectangle instance by adding the Height and Width in the rect parameter. The result of the method is a new Rectangle with the added properties.

Calling a struct Method

You can call the Add method, from Listing 12-5, through an instance of a Rectangle struct. Listing 12-6 shows how to instantiate two Rectangle structs, call the Add method and assign the result of the Add method call to another Rectangle struct.
Listing 12-5: Calling a struct Method
using System;
 
/// <summary>
/// Example of declaring and using a struct
/// </summary>
class StructExample
{
    /// <summary>
    /// Entry point: execution starts here
    /// </summary>
    static void Main()
    {
        // instantiate a new Rectangle struct
        // where Width is set to 1 and Height is set to 3
        Rectangle rect1 = new Rectangle();
        rect1.Width = 1;
        rect1.Height = 3;
 
        // show the value of Width and Height for rect1
        Console.WriteLine("rect1:  {0}:{1}", rect1.Width, rect1.Height);
 
        // instantiate a new Rectangle struct
        // where Width is set to 5 and Height is set to 7
        Rectangle rect2 = new Rectangle(5, 7);
 
        // show the value of Width and Height for rect2
        Console.WriteLine("rect2:  {0}:{1}", rect2.Width, rect2.Height);
 
        // invoke the Add method on the rect1 Rectangle struct instance,
        // passing the rect2 Rectangle struct instance as an argument
        // and assigning the new copy of the value returned by the
        // Add method to the rect3 Rectangle struct.
        Rectangle rect3 = rect1.Add(rect2);
 
        // show the value of Width and Height for rect3
        Console.WriteLine("rect3:  {0}:{1}", rect3.Width, rect3.Height);
 
        Console.ReadKey();
   }
}
In the Main method of Listing 12-5, the code instantiates rect1 and rect2, which are both Rectangle structs, assigning values to their Height and Width properties. The struct instantiation examples should be familiar by now because they are the same as earlier examples. What's useful about Listing 12-5 is the highlighted code, which shows how to invoke the Add method of the Rectangle struct. The code invokes the Add method of the rect1 instance and passes rect2 as the Rectangle struct to be added to rect1. The Add method in Listing 12-4 shows what happens when this code executes. In Listing 12-5, the return value of the Add method is assigned to rect3, which is a larger Rectangle with each of its sides equal to the sum of the individual sides of rect1 and rect2. Here's the output:
rect1: 1:3 
rect2: 5:7 
rect3: 6:10

Summary

This lesson described what a struct was and identified a few differences between class and struct types. You learned how to create a struct. You can instantiate a struct either via a default constructor or a custom constructor overload that you write. You also saw how to implement properties and methods in structs.

Struct and Classes

In C++, a struct is not very different from a class, except for the default accessibility of members. The situation is dramatically different in C#. Java, a language similar to C# in many ways, does not have structs. The basic reason is the ability to create types with value semantics, which, if properly used, leads to better performance in a managed environment.

Why we need Structs?

.NET supports the notion of value types and reference types (in Java, you can define only reference types). Instances of reference types get allocated in the managed heap and are garbage collected when there are no outstanding references to them. Instances of value types, on the other hand, are allocated in the stack, and hence allocated memory is reclaimed as soon as their scope ends. And of course, value types get passed by value (duh!), and reference types by reference. All C# primitive data types, except for System.String, are value types.
In C#, structs are value types, classes are reference types. There are two ways you can create value types, in C#, using the enum keyword and the struct keyword. Using a value type instead of a reference type will result in fewer objects on the managed heap, which results in lesser load on the garbage collector (GC), less frequent GC cycles, and consequently better performance. However, value types have their downsides too. Passing around a big struct is definitely costlier than passing a reference, that's one obvious problem. The other problem is the overhead associated with boxing/unboxing.

Classes and Structs

   public struct Foo
   {
      // Fields
 
      private string fooString;
      private int fooNumber;
 
      // Property
 
      public string FooString
      {
         get
         {
            return fooString;
         }
         set
         {
            fooString = value;
         }
      }
 
      // Method
 
      public int GetFooNumber()
      {
         return fooNumber;
      }
   }
A struct is very much like classes.

1. Structs and Inheritance

structs derive from System.ValueType whereas classes derive from System.Object or one of its descendants. Of course, System.ValueType again derives from System.Object, but that's beside the point. structs cannot derive from any other class/struct, nor can they be derived from. However, a struct can implement any number of interfaces. Be aware, though, that when you treat the struct as an interface, it gets implicitly boxed, as interfaces operate only on reference types. So, if you do something like the following:
struct Foo : IFoo
   {
      int x;
   }
and then:
IFoo iFoo = new Foo();
an instance of Foo is created and boxed. All interface method calls then execute only on the boxed instance.

What is heap and stack?

The stack is a place in the computer memory where all the variables that are declared and initialized before runtime are stored. The heap is the section of computer memory where all the variables created or initialized at runtime are stored.

What are the memory segments?

The distinction between stack and heap relates to programming. When you look at your computer memory, it is organized into three segments:
  • text (code) segment
  • stack segment
  • heap segment
The text segment (often called code segment) is where the compiled code of the program itself resides. When you open some EXE file in Notepad, you can see that it includes a lot of "Gibberish" language, something that is not readable to human. It is the machine code, the computer representation of the program instructions. This includes all user defined as well as system functions.

What is stack?

The two sections other from the code segment in the memory are used for data. The stack is the section of memory that is allocated for automatic variables within functions.
Data is stored in stack using the Last In First Out (LIFO) method. This means that storage in the memory is allocated and deallocated at only one end of the memory called the top of the stack. Stack is a section of memory and its associated registers that is used for temporary storage of information in which the most recently stored item is the first to be retrieved.

What is heap?

On the other hand, heap is an area of memory used for dynamic memory allocation. Blocks of memory are allocated and freed in this case in an arbitrary order. The pattern of allocation and size of blocks is not known until run time. Heap is usually being used by a program for many different purposes.
The stack is much faster than the heap but also smaller and more expensive.

Heap and stack from programming perspective

Most object-oriented languages have some defined structure, and some come with so-called main() function. When a program begins running, the system calls the function main() which marks the entry point of the program. For example every C, C++, or C# program must have one function named main(). No other function in the program can be called main(). Before we start explaining, let's take a look at the following example:
int x;                           /* static stack storage */
void main() {
   int y;                        /* dynamic stack storage */
   char str;                    /* dynamic stack storage */
   str = malloc(50);        /* allocates 50 bytes of dynamic heap storage */
   size = calcSize(10);       /* dynamic heap storage */
When a program begins executing in the main() function, all variables declared within main() will be stored on the stack.
If the main() function calls another function in the program, for example calcSize(), additional storage will be allocated for the variables in calcSize(). This storage will be allocated in the heap memory segment.
Notice that the parameters passed by main() to calcSize() are also stored on the stack. If the calcSize() function calls to any additional functions, more space would be allocated at the heap again.
When the calcSize() function returns the value, the space for its local variables at heap is then deallocated and heap clears to be available for other functions.
The memory allocated in the heap area is used and reused during program execution.
It should be noted that memory allocated in heap will contain garbage values left over from previous usage.
Memory space for objects is always allocated in heap. Objects are placed on the heap.
Built-in datatypes like int, double, float and parameters to methods are allocated on the stack.
Even though objects are held on heap, references to them are also variables and they are placed on stack.
The stack segment provides more stable storage of data for a program. The memory allocated in the stack remains in existence for the duration of a program. This is good for global and static variables. Therefore, global variables and static variables are allocated on the stack.

Why is stack and heap important?

When a program is loaded into memory, it takes some memory management to organize the process. If memory management was not present in your computer memory, programs would clash with each other leaving the computer non-functional.

Heap and stack in Java

When you create an object using the new operator, for example myobj = new Object();, it allocates memory for the myobj object on the heap. The stack memory space is used when you declare automatic variables.
Note, when you do a string initialization, for example String myString;, it is a reference to an object so it will be created using new and hence it will be placed on the heap.

Boxing and unboxing

The concept of boxing and unboxing is central to C#'s type system. It provides a bridge between value-types and reference-types by permitting any value of a value-type to be converted to and from type object. Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object.

Boxing Conversion

Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value of a value allocates an object instance and copies the value into the new object.

Example

This example converts an integer variable i to an object o via boxing. Then the value stored in the variable i is changed from 123 to 456. The example shows that the object keeps the original copy of the contents, 123.
// boxing.cs
// Boxing an integer variable
using System;
class TestBoxing  
{
   public static void Main() 
   {
      int i = 123;
      object o = i;  // Implicit boxing
      i = 456;       // Change the contents of i
      Console.WriteLine("The value-type value = {0}", i);
      Console.WriteLine("The object-type value = {0}", o);
   }
}

Output

The value-type value = 456
The object-type value = 123

Unboxing Conversion

Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. An unboxing operation consists of:
  • Checking the object instance to make sure it is a boxed value of the given value type.
  • Copying the value from the instance into the value-type variable.
The following statements demonstrate both boxing and unboxing operations:
int i = 123;          // A value type
object box = i;       // Boxing
int j = (int)box;     // Unboxing
For an unboxing conversion to a given value type to succeed at run time, the value of the source argument must be a reference to an object that was previously created by boxing a value of that value type. If the source argument is null or a reference to an incompatible object, an InvalidCastException is thrown.

Example

The following example demonstrates a case of invalid unboxing, of how incorrect unboxing leads to InvalidCastException. By using try and catch, an error message is displayed when the error occurs.
using System;
public class UnboxingTest 
{
   public static void Main() 
   {
      int intI = 123;
 
      // Boxing
      object o = intI;
 
      // Reference to incompatible object produces InvalidCastException
      try 
      {
         int intJ = (short) o;
         Console.WriteLine("Unboxing OK.");
      }
 
      catch (InvalidCastException e) 
      {
         Console.WriteLine("{0} Error: Incorrect unboxing.",e);
      }
   }
}

Output

System.InvalidCastException

   at UnboxingTest.Main() Error: Incorrect unboxing.
If you change the statement:
int intJ = (short) o;
to:
int intJ = (int) o;
the conversion will be performed, and you will get the output Unboxing OK.

Variables:

Variables are used to store values. More technically, a variable binds an object (in the general sense of the term, i.e. a specific value) to an identifier (the
variable's name) so that the object can be accessed later. Variables can, for example, store a value for later use:
string name = "Dr. Jones";
//here name is a string variable and “Dr. Jones” is a value stored in name variable.
Console.WriteLine("Good morning " + name); //
later use of variable
There are 3 types of variable in C Sharp.
Instance Variable                             Local Variable                                    Static Variable
Instance and Static gets the default value but local variable must be initialized.
0 is the default for int type.
Null is the default for string type.
False is the default for bool type.
Class Program
{
int i; \\instance variable
static bool b; \\static variable
static void Main(String[] args)
{
int i = 0; j = 0; //local variable
Console.WriteLine(i);
Console.WriteLine(j);
}
}
Instance variable can be used by object of class.
public class hello
{
string i = "hello"; //instance variable
static int j = 25; //static variable
static void Main(string[] args)
{
hello m = new hello(); // object is created
Console.WriteLine(m.i); // instance varible is called through object
m.display(); //non-static method is called through object
Console.ReadLine();
}
void display() // non static method
{
Console.WriteLine(hello.j); //static variable is called using the class name
}
}
Data types

Integer Data Types

Type
Description
Minimum
Maximum
Bits
bool
Boolean flag
false
true
1
byte
Unsigned Byte
0
255
8
sbyte
Signed Byte
-128
127
8
short
Signed Short Integer
-32,768
32,767
16
ushort
Unsigned Short Integer
0
65,535
16
int
Signed Integer
-2,147,483,648
2,147,483,647
32
uint
Unsigned Integer
0
4,294,967,295
32
long
Signed Long Integer
-9x1018
9x1018
64
ulong
Unsigned Long Integer
0
1.8x1019
64

Non-Integer (Floating Point) Data Types

Type
Description
Scale
Precision
Bits
float
Single Precision Number
1.5x10-45 to 3.4x1038
7 digits
32
double
Double Precision Number
5x10-324 to 1.7x10308
15 or 16 digits
64
decimal
Decimal Number
10-28 to 1028
28 or 29 digits
128

Operators

Arithmetic : +, -, *, /, %
Assignment: +=, -=, *=, /=, %=, =, !=
increment/decrement: ++, --,
Logical : &&, ||, !
twinery-?
??
null
Comparision <, <=, >, >=, ==

Twinery

int?myInt = null;
int yourInt = myInt??56;
Console.WriteLine("The value of yourInt is\n"+yourInt);
the result is 56.
note: to assign a null value to the primitive data type we use a question mark after the data type name
int?myInt = null;
int yourInt = myInt??56;
to assign a value to null data type
Enumerations
An enumeration is a data type that enumerates a set of items by assigning to each of them
an identifier (a name), while exposing an underlying base type for ordering the elements of the
enumeration. The underlying type is int by default, but can be any one of the integral types except
for char.
Enumerations are declared as follows:
enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
};
The elements in the above enumeration are then available as constants:
Weekday day = Weekday.Monday;
if (day == Weekday.Tuesday)
{
Console.WriteLine("Time sure flies by when you program in C#!");
}


    No comments:

    Post a Comment