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 أن تحمل أي نوع وأن يكون لها قيم مختلفة لكل نسخة (instance). وبمجرد انتهاء المُنشئ (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

جرّب بنفسك

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