في المقال ده، هنتكلم بالتفصيل عن الـ Console class في لغة C#، وهنشوف إزاي نستخدم الـ Properties والـ Methods بتاعته عشان نتعامل مع واجهة المستخدم في تطبيقات الـ console.

What is Console Class in C#?

علشان نقدر نعمل user interface في Console Application، مايكروسوفت وفرت لنا class اسمه Console. الـ class ده موجود جوه الـ System namespace، وعشان نستخدمه لازم نكتب using System; في أول الكود بتاعنا.

الـ Console class بيوفر شوية methods و properties بنستخدمها عشان نتعامل مع نافذة الـ console، سواء عشان ناخد مدخلات من المستخدم (user input) أو عشان نعرض مخرجات (output).

الـ Console class بيعتبر static class، وده معناه إنه مش بيتورث (cannot be inherited). ولأنه static، فكل الـ Properties والـ Methods اللي جواه بتكون static برضه. ده بيخلينا نقدر نوصلها مباشرة باستخدام اسم الـ class نفسه (Console) من غير ما نحتاج نعمل منه instance أو object.

Displaying Output

عشان نطبع أي حاجة على شاشة الـ console، عندنا طريقتين أساسيتين: Console.Write() و Console.WriteLine().

Write vs. WriteLine

الفرق الأساسي بينهم بسيط جدًا:

  • الـ Write(): بتكتب النص اللي بتديهولها، والمؤشر (cursor) بيفضل واقف في نفس السطر بعد النص مباشرةً.
  • الـ WriteLine(): بتكتب النص، وبعدين بتنقل المؤشر لسطر جديد.

Example

المثال ده بيوضح الفرق بينهم بشكل عملي:

using System;
 
namespace MyFirstProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // WriteLine() prints the value and moves the cursor to the next line
            Console.WriteLine("Hello");
 
            // Write() prints the value and stays in the same line
            Console.Write("HI ");
 
            // Write() prints the value and stays in the same line
            Console.Write("Bye ");
 
            // WriteLine() prints the value and moves the cursor to the next line
            Console.WriteLine("Welcome");
            
            // Write() prints the value and stays in the same line
            Console.Write("C#.NET ");
 
            Console.ReadKey();
        }
    }
}

النتيجة (Output):

Hello
HI Bye Welcome
C#.NET 

ده رسم توضيحي للفرق بينهم:

sequenceDiagram
    participant App as Console App
    App->>App: Console.WriteLine("Hello");
    Note right of App: Write Hello and make new line
    App->>App: Console.Write("HI ");
    Note right of App: Write HI and be in same line
    App->>App: Console.Write("Bye ");
    Note right of App: Write Bye and be in same line
    App->>App: Console.WriteLine("Welcome");
    Note right of App: Write Welcome and make new line

Printing Variable Values

لو عايز تطبع قيمة متغير (variable) مع نص، فيه كذا طريقة تعمل بيها كده:

  1. طريقة اللزق + (Concatenation): باستخدام علامة الـ + عشان تلزق النصوص في المتغيرات.

    string Name = "Ahmed";
    int Age = 30;
    // Using + to combine strings and variables
    Console.WriteLine("Hello Mr " + Name + " - Your age is " + Age);
  2. طريقة الأقواس { } (Placeholders): بتحط أرقام جوه أقواس {0}، {1} كـ “أماكن محجوزة”، وبعدين بتبعت المتغيرات بالترتيب بعد الفاصلة.

    string Name = "Ahmed";
    int Age = 30;
    // Using numbered placeholders {0}, {1}
    Console.WriteLine("Hello Mr {0} - Your age is {1}", Name, Age);
  3. طريقة الدولار $ (String Interpolation): دي الطريقة الأحدث والأسهل. بتحط علامة $ قبل علامة التنصيص "، وبعدين تكتب اسم المتغير جوه الأقواس {} مباشرةً.

    string Name = "Ahmed";
    int Age = 30;
    // Using string interpolation with $
    Console.WriteLine($"Hello Mr {Name} - Your age is {Age}");

Reading User Input

فيه 3 methods أساسية عشان ناخد مدخلات من المستخدم: ReadLine() و Read() و ReadKey().

ReadLine(): Reading a Full Line

دي أشهر method عشان نخلي البرنامج يتفاعل مع المستخدم.

  • الـ method دي بتقف مستنية المستخدم يكتب أي حاجة ويدوس Enter.
  • هي بتقرا كل اللي اتكتب لحد ما المستخدم داس Enter.
  • نقطة مهمة جدًا: الـ Console.ReadLine() دايمًا بترجع الداتا اللي المستخدم دخلها على هيئة string (نص)، لأن المستخدم ممكن يدخل أي حاجة (حروف، أرقام، رموز).
Console.Write("Please enter your name: "); // Ask the user for input
 
// Read the input from the user and store it in the userName variable
String userName = Console.ReadLine();
 
// Print the username back to the console
Console.WriteLine("Username is: " + userName);

Handling Numeric Input

هنا بتحصل مشكلة. لو حاولت تخزن اللي راجع من Console.ReadLine() في متغير نوعه رقم (زي int) مباشرةً، الكود هيديك Error.

// This will cause a compile-time error
// int age = Console.ReadLine(); // ERROR! Cannot implicitly convert type 'string' to 'int'

الحل إيه؟ لازم نعمل تحويل صريح للنوع، يعني نقول للـ C# بنفسنا: “حاول تحول الـ string ده لرقم”. العملية دي اسمها Parsing.

فيه طريقتين مشهورين للتحويل:

  1. الـ Convert.ToInt32(): جزء من class اسمه Convert بيحول بين أنواع كتير.
  2. الـ int.Parse(): دي method جوه النوع int نفسه ومخصصة للتحويل من string.
Console.Write("Enter your age: ");
string ageInput = Console.ReadLine(); // Read input as string first
 
// Method 1: Using Convert.ToInt32
int ageUsingConvert = Convert.ToInt32(ageInput);
Console.WriteLine("Your age (using Convert) is: " + ageUsingConvert);
 
// Method 2: Using int.Parse
int ageUsingParse = int.Parse(ageInput);
Console.WriteLine("Your age (using Parse) is: " + ageUsingParse);

تحذير: لو استخدمت الطريقتين دول والمستخدم دخل حاجة مينفعش تتحول لرقم (زي حروف)، البرنامج هيضرب وهيرمي Exception.

The Safe Way to Parse: TryParse()

عشان نتجنب مشكلة الـ Exception، فيه طريقة أكتر أمانًا للتحويل اسمها TryParse().

إيه الفرق؟

  • الـ TryParse() مش بترمي Exception لو التحويل فشل.
  • بدلًا من كده، هي بترجع قيمة bool (true أو false). لو true يبقى التحويل نجح، ولو false يبقى فشل.
  • لو التحويل نجح، القيمة المتحولة بتتحط في متغير بنمررهولها باستخدام كلمة out.
graph TD
    A["User enters '123'"] --> B{"int.TryParse('123', out num)"};
    B -- Returns true --> C[التحويل نجح];
    C --> D[المتغير 'num' قيمته دلوقتي 123];

    E["User enters 'abc'"] --> F{"int.TryParse('abc', out num)"};
    F -- Returns false --> G[التحويل فشل];
    G --> H[الكود اللي في 'else' هيشتغل، والبرنامج مش هيضرب];

استخدام TryParse() يعتبر Best Practice لأنه بيخليك تتحكم في حالة الفشل من غير ما البرنامج يقف.

Example

Console.Write("Enter a non-negative integer to calculate its factorial: ");
string numberInput = Console.ReadLine(); // Read input as string
 
int num; // Variable to store the parsed number
 
// Try to parse the input string into an integer.
// It returns true if parsing succeeds, false otherwise.
// If true, the parsed value is stored in the 'num' variable (because of 'out').
if (int.TryParse(numberInput, out num) && num >= 0)
{
    // Parsing succeeded and number is valid, proceed with calculation
    long factorial = 1; // Use long to handle larger numbers
    for (int i = 2; i <= num; i++)
    {
        factorial *= i;
    }
    Console.WriteLine($"The factorial of {num} is: {factorial}");
}
else
{
    // Parsing failed or number was negative
    Console.WriteLine("Invalid input. Please enter a valid non-negative integer.");
}

Read vs. ReadKey

  • الـ Read(): بتقرا حرف واحد بس من الكيبورد وبترجع الـ ASCII value بتاعته (وده رقم int).
  • الـ ReadKey(): بتقرا ضغطة زرار واحدة وبترجع object من نوع ConsoleKeyInfo فيه كل المعلومات عن الزرار اللي اتداس عليه. غالبًا بنستخدمها عشان نوقف الشاشة لحد ما المستخدم يدوس على أي زرار.

Example

using System;
 
namespace MyFirstProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter a Key (for Read):");
            // Read() returns the ASCII value of the first character entered
            int var1 = Console.Read();
            Console.WriteLine($"ASCII Value is: {var1}");
 
            // Flush the input buffer before the next read
            Console.ReadLine(); 
 
            Console.WriteLine("\nEnter a Key (for ReadKey):");
            // ReadKey() returns a ConsoleKeyInfo object
            ConsoleKeyInfo var2 = Console.ReadKey();
            Console.WriteLine($"\nKey: {var2.Key}, Char: {var2.KeyChar}, ASCII: {(int)var2.KeyChar}");
            
            Console.ReadKey();
        }
    }
}
graph TD
    subgraph User Input
        direction LR
        A[Press 'A' key]
    end

    subgraph "Read()"
        B["Console.Read()"] --> C{Returns int};
        C --> D["65 (ASCII for 'A')"];
    end

    subgraph "ReadKey()"
        E["Console.ReadKey()"] --> F{Returns ConsoleKeyInfo Object};
        F --> G["{ Key: A, KeyChar: 'a', ... }"];
    end

    A --> B;
    A --> E;

Console Properties

الـ Console class فيه خصائص كتير بنستخدمها عشان نغير شكل النافذة، ودي أهمها:

  • الـ Title: بتحدد العنوان اللي بيظهر في الـ title bar بتاع نافذة الـ console.
  • الـ BackgroundColor: بتحدد لون خلفية الـ console.
  • الـ ForegroundColor: بتحدد لون النص (الكتابة) في الـ console.
  • الـ CursorSize: بتحدد ارتفاع مؤشر الكتابة (نسبة مئوية من 1 لـ 100).

Example

using System;
 
namespace MyFirstProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Understanding Console Class";
            Console.BackgroundColor = ConsoleColor.Blue;
            Console.ForegroundColor = ConsoleColor.White;
            
            // Clear the console to apply the new colors to the whole screen
            Console.Clear(); 
            
            Console.WriteLine("BackgroundColor is now Blue");
            Console.WriteLine("ForegroundColor is now White");
            
            // Make a Beep Sound
            Console.Beep(); 
            
            // Reset colors to default
            Console.ResetColor();
            Console.WriteLine("\nColors are back to default.");
            
            Console.ReadKey();
        }
    }
}

Practical Examples

دلوقتي هنشوف أمثلة عملية بتجمع كل اللي اتعلمناه.

Employee Details Example

برنامج بيطلب من المستخدم يدخل بيانات موظف ويطبعها.

using System;
 
namespace MyFirstProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Ask User to Enter the Employee Details
            Console.WriteLine("--- Enter Employee Details ---");
            
            Console.Write("Enter Employee ID: ");
            int employeeID = Convert.ToInt32(Console.ReadLine());
            
            Console.Write("Enter Employee Name: ");
            string name = Console.ReadLine();
            
            Console.Write("Enter Employee Salary: ");
            int salary = Convert.ToInt32(Console.ReadLine());
            
            Console.Write("Enter Employee Address: ");
            string address = Console.ReadLine();
            
            Console.Write("Enter Employee Department: ");
            string department = Console.ReadLine();
 
            // Display the Entered Employee Details
            Console.WriteLine("\n--- Entered Employee Details ---");
            Console.WriteLine($"Employee ID Is: {employeeID}");
            Console.WriteLine($"Employee Name Is: {name}");
            Console.WriteLine($"Employee Salary Is: {salary}");
            Console.WriteLine($"Employee Address Is: {address}");
            Console.WriteLine($"Employee Department Is: {department}");
            
            Console.ReadKey();
        }
    }
}

Student Marks Example

برنامج بياخد بيانات طالب ودرجاته، ويحسب المجموع والمتوسط.

using System;
 
namespace MyFirstProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Ask the user to Enter Student Details
            Console.WriteLine("--- Enter Student Details ---");
            
            Console.Write("Enter Registration Number: ");
            int regdNumber = Convert.ToInt32(Console.ReadLine());
            
            Console.Write("Enter Name: ");
            string name = Console.ReadLine();
            
            Console.WriteLine("Enter Marks of three Subjects:");
            Console.Write("Subject 1: ");
            int mark1 = Convert.ToInt32(Console.ReadLine());
            
            Console.Write("Subject 2: ");
            int mark2 = Convert.ToInt32(Console.ReadLine());
            
            Console.Write("Subject 3: ");
            int mark3 = Convert.ToInt32(Console.ReadLine());
            
            int totalMarks = mark1 + mark2 + mark3;
            double averageMark = totalMarks / 3.0; // Use 3.0 for double division
 
            // Display the Student Details
            Console.WriteLine("\n--- Student Details ---");
            Console.WriteLine($"Registration Number: {regdNumber}");
            Console.WriteLine($"Name: {name}");
            Console.WriteLine($"Total Marks: {totalMarks}");
            Console.WriteLine($"Average Mark: {averageMark}");
            
            Console.ReadKey();
        }
    }
}