• Enum Ex1 →

    • Enum values represents integer values
      • Enum rename of int values (saved in memory as int values)
      • Enum → int values have names
      • default integer values is ( 0 - 1 - 2 - ….. ).
      • In this ex → (A → 0), (B → 1), (C → 2), (D → 3), (F → 4).
    • MyG = (Grades) 2; → explicit casting for integer type 2 to Enum type.
      • if 2 has a value in the Enum, MyG will store this value.
      • if 2 doesn't have a value in the Enum, MyG will store 2.
    namespace EnumEx1
    {
    		enum Grades
    		{
    		    A , B , C , D , F
    		}
    		
    		class program 
    		{
    		    Grades MyG = Grades.C;
    
            MyG = Grades.F;
    
            if (MyG == Grades.F)
                Console.WriteLine(":(");
    
            MyG = (Grades)2;
    
            Console.WriteLine(MyG); // output -> C
    
            MyG = (Grades)8;
    
            Console.WriteLine(MyG); // output -> 8
    		}
    }
    

  • Enum Ex2 →

    • int values can be changed.
    • int data type can be changed to → byte - short - long - .…
      • enum Grades : byte {}
    • In this Ex →
      • SV = 201, NasrCity = 105, Alex = 223.
      • (Assuit, Ismailia, Mansoura) → will take byte value starting from last initialized value →
        • (Assuit → 224), (Ismailia → 225), (Mansoura → 226).
    namespace EnumEx2
    {
    		enum Branches:byte
    		{
    		    SV = 201 , NasrCity = 105 , Alex = 223 , Assuit , Ismailia , Mansoura
    		}
    		
    		class program
    	{
            Branches MYB = new Branches();
    
            MYB = Branches.Ismailia;
    
            Console.WriteLine(MYB);
    		}
    		
    }
    

  • Enum Ex3 →

    • we can use Enum as bit flag to check permissions.
    • (Read → 1000), (Write → 0100), (Execute → 0010), (Delete → 0001).
    namespace EnumEx2
    {
    		[Flags]
        enum Permissions:byte
        {
            Read = 0x08 , Write = 4 , Execute = 0b_0000_0010 ,
            Delete = 0x01 , RootUser = 0x0F
        }
        
        class program 
    		{
    	      Permissions MyP = Permissions.Read;
    	
    	      Console.WriteLine(MyP);
    	
    	      MyP ^= Permissions.Write; // ^= XOR
    	      // 1000 XOR 0100 -> 1100
    	
    	      if ((MyP & Permissions.Read) == Permissions.Read)
    	          Console.WriteLine("R");
    	      else
    	          Console.WriteLine("Not R");
    	
    	      Console.WriteLine(MyP);
    	
    	      MyP ^= Permissions.Read;
    	      // 1100 XOR 1000 -> 0100
    	
    	      Console.WriteLine(MyP);
    	
    	      MyP = (Permissions)15; // int casting to enum
    		    //MyP = RootUser
    	
    	      if ((MyP & Permissions.Read) == Permissions.Read)
    	          Console.WriteLine("R");
    	      else
    	          Console.WriteLine("Not R");
    	
    	      Console.WriteLine(MyP);
    	  }
    }
    

  • Properties →

    • set → 1 input parameter
    • get → 0 input parameter
    • no property take more than 1 input parameter
    namespace Properties
    {
    		struct Employee
    		{
    				public int ID;
    
            string Name; 
    				// basic get function
            public string GetName ()
            {
                return Name;
            }
    				//basic set function 
            internal void SetName ( string name)
            {
                Name = name.Length <= 20 ? name : name.Substring(0, 20);
            }
    
            decimal salary;
    				// set & get property
            public decimal Salary
            {
                get { return salary; }
                internal set { salary = value >= 1200 ? value : 1200; }
                // condition ? value_1 : value_2 -> if (?) else (:)
            }
    				// self computed property
    				// property with pre initialized attribute
    				// and compiler create the attribute while combiling
    				// we use this property by its name not attribute name
    				// attribute made by compiler not reachable
            public decimal Deductions
            {
                get { return 0.11M * salary; }
            }
    				// struct constructor
    				// in struct constructor we must initialize all struct attributes
            public Employee(int _id , string _Name , decimal _salary)
            {
                ID = _id;
                Name = _Name;
                salary = _salary;
            }
    
            public override string ToString()
            {
                return $"{ID}::{Name}::{salary}";
            }
            }
    		}
    		
    		void main()
    		{
    		    Employee E = new();
    
            E.ID = 10;
    
            Console.WriteLine(E.ID);
    
            E.SetName("Ahmed Aly");
    
            Console.WriteLine(E.GetName());
    
            E.Salary = 1000; ///Set
    
            Console.WriteLine(E.Salary); ///Get
    
            Console.WriteLine(E.Deductions);
    
            //E.Deductions = 101; //read only property
    		}
    
    }
    

  • Indexer →

    • Indexer → property take more than 1 input parameter.
    namespace Indexer 
    {
    		struct PhoneBook
        {
            string[] Names;
            long[] Numbers;
            int size;
    
            public int Size { get { return size; } }
    
            public PhoneBook(int _Size)
            {
                size = _Size;
                Names = new string[size];
                Numbers = new long[size];
            }
    
            public void SetEntry (int Index , string Name , long Number )
            {
                if ((Index>=0)&&(Index < size))
                {
                    Names[Index] = Name;
                    Numbers[Index] = Number;
                }
            }
    
            public long GetNumber (string Name)
            {
                for (int i = 0; i < Names?.Length; i++)
                    if (Names[i] == Name)
                        return Numbers[i];
                return -1;
            }
    
            public long this[string Name]
            {
                get
                {
                    for (int i = 0; i < Names?.Length; i++)
                        if (Names[i] == Name)
                            return Numbers[i];
                    return -1;
                }
                set
                {
                    for (int i = 0; i < Names?.Length; i++)
                        if (Names[i] == Name)
                            Numbers[i] = value;
                }
            }
    
            public string this[int Index]
            {
                get
                {
                    if ((Index >= 0) && (Index < size))
                        return $"{Names[Index]}:::{Numbers[Index]}";
                    return "NA";
                }
            }
    
            public long this [int Index , string Name]
            {
                set
                {
                    if ((Index >= 0) && (Index < size))
                    {
                        Names[Index] = Name;
                        Numbers[Index] = value;
                    }
                }
            }
    
        }
    	
    		void main()
    		{
    				PhoneBook book = new PhoneBook(5);
    
            book.SetEntry(0, "ABC", 123);
            book.SetEntry(1, "XYZ", 456);
            book.SetEntry(2, "KLM", 789);
    
            book[3, "DEF"] = 101;
    
            book["XYZ"] = 654;
    
            Console.WriteLine(
                //book.GetNumber("XYZ")
                book["XYZ"]
                );
    
            for (int i = 0; i < book.Size; i++)
                Console.WriteLine(book[i]);
    
            //String Str = "12341";
    
            //if (Str[0] == 1) ;
    
            //Str[0] = '2'; 
    		}
    }
    

  • Interface →

    • interface → prototype - code contract - no data in
    • if class follows an interface we must initialize all interface (methods, properties) in the class

    Ex1 →

    namespace InterfaceEx1
    {
    
    		interface ISeries
    		{
    				int Current { get; }
    				void GetNext();
    				void Reset();
    		}
    	
    		class FibSeries : ISeries
    		{
    				int current;
    				int prev;
    				public FibSeries()
    				{
    						prev = 0;
    						current = 1;
    				}
    				public int Current { get { return current; } }
    				public void GetNext()
    				{
    						int Temp = Current;
    						current += prev;
    						prev = Temp;
    				}
    				public void Reset()
    				{
    						current = 1;
    						prev = 0;	
    				}
    		}
    			
    		struct SeriesByTwo : ISeries
    	  {
    		    int current;
    		    public int Current { get { return current; } }
    		
    		    public void GetNext()
    		    {
    			       current += 2;
    		    }
    		
    		    public void Reset()
    		    {
    			       current = 0;
    		    }
    	  }
    	  
    	  class Program
    	  {
    			  public static void ProcessSeries (ISeries series)
            {
                for ( int i=0; i < 10; i++)
                {
                    Console.Write($"{series.Current} , ");
                    series.GetNext();
                }
                Console.WriteLine("");
                series.Reset();
            }
            
            static void MainV1(string[] args)
            {
    		        SeriesByTwo series01 = new SeriesByTwo();
    
                ProcessSeries(series01);
    
                ISeries series02; ///Valid ,
                //Refrence to any Class\\Struct Implementing ISeries Interface
                //series01 = new ISeries(); ///Not Valid
    
                series02 = new FibSeries();
    
                ProcessSeries(series02);
            }
    	  }
    	  
    }
    

    Ex2 →

    namespace D04
    {
        interface IMyType
        {
            //int X; Not Supported
    
            void FunOne();
    
            decimal Salary { get; set; }
    
            ///C# 8.0 Feature m Default Implemented Methods
            //internal void FunTwo ()
            //{
            //    Console.WriteLine("Inside Interface");
            //}
        }
    
        struct MyType : IMyType
        {
            public decimal Salary 
            {
                get { return 0; }
                set { }
            }
    
            public void FunOne()
            {
                Console.WriteLine("My Type Fun one");
            }
        }
    
    }
    

    Ex3 →

    namespace D04
    {
        struct Employee:IComparable
        {
            public int ID;
    
            string Name; 
    
            public string GetName ()
            {
                return Name;
            }
    
            internal void SetName ( string name)
            {
                Name = name.Length <= 20 ? name : name.Substring(0, 20);
            }
    
            decimal salary;
    
            public decimal Salary
            {
                get { return salary; }
                internal set { salary = value >= 1200 ? value : 1200; }
            }
    
            public decimal Deductions
            {
                get { return 0.11M * salary; }
            }
    
            public Employee(int _id , string _Name , decimal _salary)
            {
                ID = _id;
                Name = _Name;
                salary = _salary;
            }
    
            public override string ToString()
            {
                return $"{ID}::{Name}::{salary}";
            }
    
            ///return +ve this > obj
            ///return -ve this < obj
            ///return 0 this == obj
            ///items[j].compareTo(items[j+1]) //Inside Sort
            public int CompareTo(object obj)
            {
                //foreach (var item in (new StackTrace()).GetFrames())
                //    Console.WriteLine(item.GetMethod().Name);
    
                Employee Right = (Employee)obj; //UnBoxing
    
                //if (salary > Right.salary)
                //    return 1;
                //else if (salary < Right.salary)
                //    return -1;
                //else
                //    return 0;
    
                return salary.CompareTo(Right.salary);
            }
        }
        
        class Program
        {
    		    static void MainV1(string[] args)
    		    {
    				    Employee[] EArr = new Employee[3]
                {
                    new Employee(5 , "Ahmed Aly" , 17000),
                    new Employee(8 , "Sayed Aly" , 5000),
                    new Employee(2 , "Mona Aly" , 10000)
                };
    
                Array.Sort(EArr);
    
                foreach (var item in EArr)
                {
                    Console.WriteLine(item);
                }
    		    }
        }
    }
    
    

  • Exception Handling →

    Ex1 →

    creating our own exception to handle errors in our code by inherit from Exception class

    namespace EH
    {
        class NegativeNumberException:Exception
        {
            public NegativeNumberException():base("Number must be >=0")
            {
    
            }
        }
    }
    

    Ex2 →

    namespace D04
    {
        class Class1
        {
            public static void Main()
            {
                //try
                //{
                //    DoSomeWork();
                //}
                //catch ( NegativeNumberException Ex)
                //{
                //    Console.WriteLine(Ex.Message);
                //}
                //catch (Exception Ex)
                //{
                //    Console.WriteLine(Ex.Message);
                //    Console.WriteLine("Main Catch");
                //}
                // can use multiple catchs
                try
                {
                    DoSomeProtectiveWork();
                }
                catch
                {
                    Console.WriteLine("General Main Catch");
                }
    
            }
    
            public static void DoSomeProtectiveWork ()
            {
                int X, Y, Z;
    
                ///Try PArse return false , 
                //if String can't be parsed to int ,
                // No Exceptions will be fired
    
                do
                {
                    Console.WriteLine("Enter First Number");
                }
                while (!int.TryParse(Console.ReadLine(), out X));
    
                do
                {
                    Console.WriteLine("Enter Second Number");
                }
                while ((!int.TryParse(Console.ReadLine(), out Y))||(Y<=0));
    
                Z = X / Y;
    
                int[] Arr = { 3, 4, 5 };
                if (Arr?.Length > 3)
                    Arr[3] = 8;
    
            }
    
            public static void DoSomeWork ()
            {
                int X=0, Y=0, Z;
               
                try
                {
                    X = int.Parse(Console.ReadLine());
                    Y = Convert.ToInt32(Console.ReadLine());
    
                    Z = X / Y;
                    if (Y < 0)
                        throw new NegativeNumberException();
    
                    Console.WriteLine(Z);
    
                    int[] Arr = { 1, 2, 3 };
                    Arr[3] = 4;
    
                    Console.WriteLine("end of Try");
                }
                catch (DivideByZeroException Ex)
                {
                    Console.WriteLine("Y Can't Equal Zero");
                }
                catch ( ArithmeticException Ex)
                {
                }
                catch (FormatException Ex)
                {
                    Console.WriteLine("Check String Format");
                }
                //catch (Exception Ex)
                //{
                //    Console.WriteLine(Ex.Message);
                //}
                finally
                {
                    Console.WriteLine("Inside Finally");
                }
                Console.WriteLine(@"After Try \\ Catch ");
            }
        }
    }