Casting Built in Value Types →
int X = 50;
long Y = 5000;
//Y = X;
///Implicit Casting
///Int64 = Int32
///Safe Casting , No RunTime Errors
Y = long.MaxValue;
X = (int)Y;
///Int32 = Int64
///UnSafe Casting
///Explicit Casting
///Default behavior for CLR , Will not Throw OverflowException when overflow happens
///CLR will throw OverFlowException
checked
{
X = (int)Y;
}
Console.WriteLine($"X = {X}");
Console.WriteLine($"Y = {Y}");
Boxing and Unboxing →

/ System.Object & Any ValueType
int X = 5;
object O1 = new object();
O1 = X;
///Base Ref = Child
///Safe
///Boxing
O1 = "Hello";
int Y;
Y = (int)O1;
//Derived = Base
///unSafe , Explicit
///UnBoxing
Console.WriteLine(Y);
Nullable Types →
int X = 50;
//X = null; error
int? Y; ///Nullable int , IL : Nullable<int>
Y = 5000;
Y = null;
//Y = X;
///Safe Casting , Implicit
//X = (int)Y;
///UnSafe , Explicit
///Protective Programming
//if (Y != null)
// X = (int)Y;
//else
// X = 0;
//if (Y.HasValue)
// X = Y.Value;
//else
// X = 0;
//X = Y.HasValue ? Y.Value : 0;
X = Y ?? 0;
Console.WriteLine($"X = {X}");
Console.WriteLine($"Y = {Y}");
Null Operators →
double D = default;
int[] Arr = default;
//for (int i = 0; (Arr != null) && (i < Arr.Length); i++)
// Console.WriteLine(Arr[i]);
///Null Propagation Operator \\ Null Conditional Operator -> ?
for (int i = 0; i < Arr?.Length; i++)
Console.WriteLine(Arr[i]);
Employee E = default;
//Console.WriteLine(E.Dept.Name); ///Unsafe
Console.WriteLine(E?.Dept?.Name ?? "NA");
int R = Arr.Length; ///UnSafe
int? RR = Arr?.Length; ///Safe Arr?.Lenght ====> (Arr != null)? Arr.lenght: null
int RRR = Arr?.Length ?? 0; //Safe
class Dept
{
public string Name;
}
class Employee
{
public Dept Dept;
}
Implicit Typed Local Variable →
//double D = 15.3;
//Console.WriteLine(D.GetType().Name);
//D = "Hello";
var D = 15.3;
///Compiler will Detect Variable Data type
///Based on Initial Value
///Implicit Typed Local Variable
///Can't be not Initialized
///Can't be initialized with null
Console.WriteLine(D.GetType().Name);
//D = "Hello";
StackTrace →

public static void FunTwo()
{
//Console.WriteLine("Fun Two");
//int X = 0;
//int Y = 7 / X;
StackTrace sTrace = new StackTrace();
StackFrame[] sFrames = sTrace.GetFrames();
for (int i = 0; i < sFrames?.Length; i++)
Console.WriteLine(sFrames[i].GetMethod().Name);
}
public static void FunOne()
{
FunTwo();
}
Named & Default input Parameters→
// putting default value make parameter named & optional
public static void PrintLine (int N=5 , string Pattern="#")
{
//FunOne();
int i = 0;
for (; i< N; i++)
Console.Write(Pattern);
Console.WriteLine("");
}
static void MainV2 ()
{
int X;
Console.WriteLine("Enter New Value : ");
PrintLine(7, "-_-");
X = int.Parse(Console.ReadLine());
Console.WriteLine(++X);
PrintLine(5, "#");
PrintLine();
PrintLine(7);
// cant use parameter before other without named parameter
//PrintLine( , "="); ///Not Valid
///Named Input Paramters
PrintLine(Pattern: @"/**\\", N: 4);
PrintLine(Pattern: "=");
++X;
}
Value Types , pass By Value →

public static void SWAP(int X, int Y)
{
int Temp = X;
X = Y;
Y = Temp;
}
static void MainV2 ()
{
int A = 7, B = 3;
SWAP(A, B); /// Pass By Value
Console.WriteLine($"A = {A}");
Console.WriteLine($"B = {B}");
}
Value Type , Pass By Reference →

public static void SWAP(ref int X,ref int Y)
{
int Temp = X;
X = Y;
Y = Temp;
}
static void MainV2 ()
{
int A = 7, B = 3;
SWAP(ref A, ref B); /// Pass By Reference
Console.WriteLine($"A = {A}");
Console.WriteLine($"B = {B}");
}
Reference Type , Pass By Value →

public static int SumArray(int[] Arr)
{
int Sum = 0;
for (int i = 0; i < Arr?.Length; i++)
Sum += Arr[i];
Console.WriteLine(Arr.GetHashCode());
return Sum;
}
static void MainV2 ()
{
int[] MyA = { 1, 2, 3, 4, 5 };
Console.WriteLine(MyA.GetHashCode());
Console.WriteLine(SumArray(MyA));
}
Value Type , Pass By Reference = Reference Type , Pass By Value