Boxing and unboxing in C# allows developers to convert .NET data types from value type to reference type and vice versa. Converting a value type to a reference type is called called boxing in C# and converting a reference type to a value type is called unboxing in C#.
C# provides a "unified type system". All types including value types derive from the type object. It is possible to call the object methods on any value, even values of "primitive" types, such as int.
class Test
{
static void Main()
{
int i = 1;
object o = i; // boxing
int j = (int)o; // unboxing
}
}
This example shows both, boxing and unboxing. When a variable of a value type needs to be converted into a reference type, an object box is allocated to hold the value, and the value is copied into the box.
Unboxing is just the opposite. When an object box is cast back to its original value type, the value is copied out of the box and into the appropriate storage location.
Generics allow us to design classes and methods decoupled from the data types. Generic classes are extensively used by collection classes available in System.Collections.Generic namespace.
using System;
namespace Revolution
{
public class MainClass
{
private static void Main()
{
bool Equal = Calculator.AreEqual(1, 2);
if (Equal)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}
}
}
public class Calculator
{
public static bool AreEqual(int value1, int value2)
{
return value1 == value2;
}
}
}
//use of Generics
using System;
namespace Revolution
{
public class MainClass
{
private static void Main()
{
bool Equal = Calculator.AreEqual<int>(2, 1);
if (Equal)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}
}
}
public class Calculator
{
public static bool AreEqual<T>(T value1, T value2)
{
return value1.Equals(value2);
}
}
}
In this example, AreEqual(int value1, int value2) only works with int data type. If, we pass any other data type, we get a compiler error. So, AreEqual() method in Calculator class is tightly coupled with the int data type, and prevents it from being used with any other data type.
After making AreEqual() method generic, we need to specify the type, they want the method to operate on.
C# collection types are designed to store, manage and manipulate similar data more efficiently. Data manipulation includes adding, removing, finding, and inserting data in the collection. Collection types implement the following common functionality:
.NET supports two types of collections, generic collections and non-generic collections.
using System;
using System.Collections;
namespace Revolution
{
public class MainClass
{
private static void Main()
{
ArrayList al = new ArrayList();
string str = "kiran teja jallepalli";
int x = 7;
DateTime d = DateTime.Parse("8-oct-1985");
al.Add(str);
al.Add(x);
al.Add(d);
foreach (object o in al)
{
Console.WriteLine(o);
}
}
}
}
using System;
using System.Collections;
namespace Revolution
{
public class MainClass
{
private static void Main()
{
List<int> lst = new List<int>();
lst.Add(100);
lst.Add(200);
lst.Add(300);
lst.Add(400);
foreach (int i in lst)
{
Console.WriteLine(i);
}
}
}
}
A delegate is a type safe function pointer.That is, they hold reference(Pointer) to a function.
The signature of the delegate must match the signature of the function, the delegate points to, otherwise you get a compiler error. This is the reason delegates are called as type safe function pointers.
A Delegate is similar to a class. You can create an instance of it, and when you do so, you pass in the function name as a parameter to the delegate constructor, and it is to this function the delegate will point to.
using System;
// Delegate Declaration.
public delegate void HelloFunctionDelegate(string Message);
class Revolution
{
public static void Main()
{
// Create the instance of the delegate and pass in the function
// name as the parameter to the constructor. The passed in
// function signature must match the signature of the delegate
HelloFunctionDelegate del = new HelloFunctionDelegate(Hello);
// Invoke the delegate, which will invoke the method
del("Hello from Delegte");
}
public static void Hello(string strMessge)
{
Console.WriteLine(strMessge);
}
}
Var | Dynamic |
---|---|
The variables are declared using var keyword are statically typed. | The variables are declared using dynamic keyword are dynamically typed. |
The type of the variable is decided by the compiler at compile time. | The type of the variable is decided by the compiler at run time. |
The variable of this type should be initialized at the time of declaration. So that the compiler will decide the type of the variable according to the value it initialized. | The variable of this type need not be initialized at the time of declaration. Because the compiler does not know the type of the variable at compile time. |
If the variable does not initialized it throw an error. | If the variable does not initialized it will not throw an error. |
It support intelliSense in visual studio. | It does not support intelliSense in visual studio |
var myvalue = 10; // statement 1 myvalue = “revolution”; // statement 2 Here the compiler will throw an error because the compiler has already decided the type of the myvalue variable using statement 1 that is an integer type. When you try to assign a string to myvalue variable, then the compiler will give an error because it violating safety rule type. |
dynamic myvalue = 10; // statement 1 myvalue = “revolution”; // statement 2 Here, the compiler will not throw an error though the type of the myvalue is an integer. When you assign a string to myvalue it recreates the type of the myvalue and accepts string without any error. |
It cannot be used for properties or returning values from the function. It can only used as a local variable in function. | It can be used for properties or returning values from the function. |