• Casting Built in Value Types →

    • Implicit casting / Explicit casting
    • Implicit casting → y = x; → don't use casting operator (don't use data type as casting operator)
      • Safe casting → no RunTime errors (باخد الداتا من مكان ضيق احطها في مكان واسع).
    • Unsafe Casting → باخد داتا 8 بايت احطها في 4 بايت
    • Explicit Casting → using casting operator → x = (int) y;
      • any unsafe must wrote in Explicit casting
    • Overflow → باخد داتا حجمها كبير اخزنها في مكان صغير فيحصل فقد في الداتا
      • CLR will not throw a RunTime error when Overflow happens
    • checked block → لو حصل اوفر فلو يحصل اكسبشن
    • unchecked block → بستخدمها جوه تشيكد لو عاوز استثني جزء منه
    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 →

    • Time consuming (boxing and unboxing)
    • Unboxing → كومبيلر مبيقدرش يعرف هيكون في رن تايم ايرور ولا لا

    1.png

    / 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 →

    2.png

    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 →

    • change in value will be is copies only (x,y) not the original var (A,B)

    3.png

    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 →

    • change will be in original variables value.

    4.png

    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 →

    5.png

    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