Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الكلمات المفتاحية 'readonly' و 'const'

جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 16 من 70.

توفر لغة C# كلمتين رئيسيتين لإنشاء قيم لا يمكن تغييرها: const و readonly. بينما يمنع كلاهما التعديل، إلا أنهما يعملان بشكل مختلف ويخدمان أغراضاً متميزة.

يجب تعيين قيمة للحقل const عند التصريح عنه، ويتم تحديد قيمته في وقت التجميع (compile time). إنه ثابت (static) بشكل ضمني، مما يعني أنه ينتمي إلى الفئة (class) بدلاً من الكائنات (instances):

public class GameSettings
{
    public const int MaxPlayers = 4;
    public const double Gravity = 9.81;
}

يمكنك الوصول إلى الثوابت من خلال اسم الفئة: GameSettings.MaxPlayers. تعمل الثوابت فقط مع الأنواع الأولية، والسلاسل النصية، و null لأن المترجم يجب أن يعرف القيمة الدقيقة.

يمكن تعيين حقل readonly عند التصريح عنه أو في المنشئ (constructor)، ويتم تحديد قيمته في وقت التشغيل (runtime):

public class Player
{
    public readonly string Id;
    public readonly DateTime CreatedAt = DateTime.Now;
    
    public Player(string id)
    {
        Id = id;
    }
}

على عكس const، يمكن لحقول readonly أن تحمل أي نوع ويمكن أن يكون لها قيم مختلفة لكل مثيل. بمجرد انتهاء المنشئ (constructor)، لا يمكن تغيير القيمة.

استخدم const للقيم العالمية حقًا والتي لن تتغير أبدًا، مثل الثوابت الرياضية. استخدم readonly للقيم التي يجب تعيينها مرة واحدة ولكنها قد تختلف بين الكائنات أو تحتاج إلى حساب وقت التشغيل.

challenge icon

التحدي

سهل

لنقم ببناء نظام تكوين لمحاكاة فيزيائية يوضح متى يتم استخدام const للثوابت العالمية مقابل readonly للقيم التي يتم تعيينها مرة واحدة عند وقت التشغيل.

ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:

  • PhysicsConstants.cs: قم بتعريف فئة PhysicsConstants داخل مساحة الأسماء Simulation. يجب أن تحتوي هذه الفئة على ثوابت عالمية لا تتغير أبداً وهي نفسها في كل مكان:
    • حقل const باسم Gravity وقيمته 9.81
    • حقل const باسم SpeedOfLight وقيمته 299792458
    • حقل const نصي (string) باسم GravityUnit وقيمته "m/s^2"
  • Projectile.cs: قم بتعريف فئة Projectile داخل مساحة الأسماء Simulation. كل قذيفة لها قيم يجب تعيينها مرة واحدة عند إنشائها ولا يتم تعديلها بعد ذلك أبداً:
    • حقل readonly باسم Name (string)
    • حقل readonly باسم InitialVelocity (double)
    • حقل readonly باسم LaunchAngle (double، بالدرجات)
    • منشئ (constructor) يقبل ويقوم بتعيين القيم الثلاث جميعاً
    • دالة GetMaxHeight() تقوم بحساب أقصى ارتفاع باستخدام الصيغة: (velocity^2 * sin^2(angle)) / (2 * gravity). استخدم Math.Sin() وقم بتحويل الدرجات إلى راديان عن طريق الضرب في Math.PI / 180
  • Program.cs: في ملفك الرئيسي، قم بإنشاء قذيفة باستخدام قيم الإدخال واعرض الثوابت الفيزيائية جنباً إلى جنب مع أقصى ارتفاع محسوب للقذيفة.

ستتلقى ثلاثة مدخلات:

  • اسم القذيفة (Projectile name)
  • السرعة الابتدائية (Initial velocity) (بالمتر/ثانية)
  • زاوية الإطلاق (Launch angle) (بالدرجات)

اطبع المخرجات بهذا التنسيق:

Gravity: {Gravity} {GravityUnit}
Speed of Light: {SpeedOfLight} m/s
Projectile: {Name}
Initial Velocity: {InitialVelocity} m/s
Launch Angle: {LaunchAngle} degrees
Max Height: {maxHeight} m

قم بتقريب أقصى ارتفاع إلى منزلتين عشريتين باستخدام Math.Round(value, 2).

على سبيل المثال، إذا كانت المدخلات هي Rocket، و 50، و 45، يجب أن تكون المخرجات:

Gravity: 9.81 m/s^2
Speed of Light: 299792458 m/s
Projectile: Rocket
Initial Velocity: 50 m/s
Launch Angle: 45 degrees
Max Height: 63.71 m

ورقة مرجعية

توفر لغة C# كلمتين رئيسيتين لإنشاء قيم غير قابلة للتغيير (immutable): const و readonly.

يجب تعيين قيمة للحقل const عند التصريح عنه، ويتم تحديد قيمته في وقت التجميع (compile time)، ويكون ثابتًا بشكل ضمني (implicitly static):

public class GameSettings
{
    public const int MaxPlayers = 4;
    public const double Gravity = 9.81;
}

يتم الوصول إلى الثوابت من خلال اسم الفئة: GameSettings.MaxPlayers. تعمل الثوابت فقط مع الأنواع الأولية (primitive types)، والسلاسل النصية (strings)، والقيمة null.

يمكن تعيين قيمة للحقل readonly عند التصريح عنه أو داخل المشيد (constructor)، ويتم تحديد قيمته في وقت التشغيل (runtime):

public class Player
{
    public readonly string Id;
    public readonly DateTime CreatedAt = DateTime.Now;
    
    public Player(string id)
    {
        Id = id;
    }
}

يمكن لحقول readonly أن تحمل أي نوع ويمكن أن يكون لها قيم مختلفة لكل كائن (instance). بمجرد انتهاء المشيد، لا يمكن تغيير القيمة.

استخدم const للقيم العالمية التي لن تتغير أبدًا. واستخدم readonly للقيم التي يجب تعيينها مرة واحدة ولكنها قد تختلف بين الكائنات أو تحتاج إلى حساب في وقت التشغيل.

جرّب بنفسك

using System;
using Simulation;

class Program
{
    public static void Main(string[] args)
    {
        // قراءة المدخلات
        string name = Console.ReadLine();
        double velocity = Convert.ToDouble(Console.ReadLine());
        double angle = Convert.ToDouble(Console.ReadLine());

        // TODO: إنشاء كائن `Projectile` باستخدام قيم المدخلات

        // TODO: طباعة الثوابت الفيزيائية (Gravity مع الوحدة، Speed of Light)

        // TODO: طباعة معلومات المقذوف (Name، Initial Velocity، Launch Angle)

        // TODO: حساب وطباعة أقصى ارتفاع (مقرباً إلى منزلتين عشريتين)
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming