0Pricing
C# Academy · درس

الثوابت والحقول readonly

ميّزوا بين const وstatic readonly

الثوابت والحقول readonly درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

طريقتان لجعل القيم ثابتة

توفر C# الكلمتين const وreadonly للقيم التي يجب ألا تتغير. تبدوان متشابهتين، لكن سلوكهما مختلف جدًا. يقارن هذا الدرس بينهما.

using System;

class Config
{
    public const double Pi = 3.14159;
    public static readonly DateTime StartedAt = DateTime.Now;
}

class Program
{
    static void Main()
    {
        Console.WriteLine("Pi = " + Config.Pi);
    }
}

const: ثابت وقت الترجمة

يجب إسناد قيمة حرفية إلى const عند التصريح عنه، وتُضمَّن قيمته في وقت الترجمة. وهو ساكن ضمنيًا.

using System;

class Circle
{
    public const double Pi = 3.14159;

    public static double Area(double r) => Pi * r * r;
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Circle.Area(2).ToString("0.00"));
    }
}

يجب أن يكون const قيمة حرفية

بما أن حله يتم في وقت الترجمة، فلا يمكن لـ const أن يحتوي إلا على تعبير ثابت: أرقام أو سلاسل نصية أو قيم منطقية أو ثوابت أخرى.

using System;

class Limits
{
    public const int MaxRetries = 3;
    public const int Timeout = MaxRetries * 1000;   // const expression OK
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Limits.MaxRetries + ", " + Limits.Timeout);
    }
}

readonly: ثابت وقت التشغيل

يُعيَّن الحقل readonly مرة واحدة، إما عند التصريح عنه أو داخل مُنشئ، ثم لا يمكن تغييره. ويمكن حساب قيمته في وقت التشغيل.

using System;

class Session
{
    public readonly string Id;

    public Session(string id)
    {
        Id = id;   // allowed: inside constructor
    }
}

class Program
{
    static void Main()
    {
        var s = new Session("abc-123");
        Console.WriteLine("Session: " + s.Id);
    }
}

يمكن لـ readonly استخدام قيم وقت التشغيل

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

using System;

class Order
{
    public readonly Guid OrderId;

    public Order()
    {
        OrderId = Guid.NewGuid();
    }
}

class Program
{
    static void Main()
    {
        var o = new Order();
        Console.WriteLine("Has id: " + (o.OrderId != Guid.Empty));
    }
}

static readonly

استخدموا static readonly لقيمة على مستوى الفئة تُحسب مرة واحدة في وقت التشغيل. وهذا هو البديل المعتاد لـ const عندما لا تكون القيمة حرفية.

using System;

class AppInfo
{
    public static readonly string[] Roles = { "admin", "user", "guest" };
}

class Program
{
    static void Main()
    {
        Console.WriteLine("Roles: " + Roles());
    }

    static int Roles() => AppInfo.Roles.Length;
}

لماذا قد تكون const محفوفة بالمخاطر بين التجميعات

نظرًا إلى أن قيم const تُضمَّن في الشيفرة المستدعية وقت الترجمة، فإن تغيير public const في مكتبة يتطلب إعادة ترجمة جميع الشيفرات المستدعية. أما static readonly فتتجنب ذلك.

using System;

class Lib
{
    public const int Version = 2;              // inlined into callers
    public static readonly int Build = 100;     // read at runtime
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Lib.Version + "." + Lib.Build);
    }
}

لا يمكن إعادة إسناد أيٍّ منهما

بعد التهيئة، لا يمكن تغيير حقل const أو حقل readonly. وتؤدي محاولة ذلك إلى خطأ في الترجمة.

using System;

class Demo
{
    public const int A = 10;
    public readonly int B;

    public Demo() { B = 20; }
    // A = 11;  // would not compile
    // B = 21;  // would not compile outside constructor
}

class Program
{
    static void Main()
    {
        var d = new Demo();
        Console.WriteLine(Demo.A + ", " + d.B);
    }
}

الاختيار بينهما

استخدم const للقيم الحرفية الفعلية التي لا تتغير مطلقًا، مثل Pi وMaxInt. واستخدم readonly عندما تُحسَب القيمة وقت التشغيل أو قد تختلف من كائن إلى آخر.

using System;

class Physics
{
    public const double Gravity = 9.81;          // universal literal
    public readonly double Mass;                  // per object

    public Physics(double mass) { Mass = mass; }
    public double Weight() => Mass * Gravity;
}

class Program
{
    static void Main()
    {
        var p = new Physics(10);
        Console.WriteLine("Weight: " + p.Weight());
    }
}

تنبيه بشأن مرجع readonly

يقفل readonly الحقل، وليس الكائن الذي يشير إليه. فلا يمكن إعادة إسناد مرجع قائمة readonly، لكن يمكن أن تتغير محتوياتها.

using System;
using System.Collections.Generic;

class Cart
{
    public readonly List<string> Items = new List<string>();
}

class Program
{
    static void Main()
    {
        var c = new Cart();
        c.Items.Add("Pen");   // allowed: mutating the object
        c.Items.Add("Book");
        Console.WriteLine("Items: " + c.Items.Count);
    }
}

تجميع المفاهيم

يستخدم الصنف المعتاد const للقيم الحرفية الثابتة، وreadonly للقيم التي تثبت لكل كائن وقت إنشائه.

using System;

class Account
{
    public const decimal MinBalance = 0m;
    public readonly string Owner;

    public Account(string owner)
    {
        Owner = owner;
    }
}

class Program
{
    static void Main()
    {
        var a = new Account("Rin");
        Console.WriteLine(a.Owner + " min=" + Account.MinBalance);
    }
}

اختبار سريع

اختبر مدى فهمك للفرق بين const وreadonly.

مراجعة

إن const قيمة حرفية وقت الترجمة، وهي static ضمنيًا وتُضمَّن في الشيفرات المستدعية. أما readonly فتُضبط مرة واحدة عند التصريح أو داخل المُنشئ، ويمكنها استخدام قيم وقت التشغيل. استخدم const للقيم الحرفية الفعلية، وstatic readonly للقيم المشتركة المحسوبة وقت التشغيل، وتذكّر أن readonly يقفل المرجع لا الكائن.

using System;

class Demo
{
    public const int Max = 100;
    public readonly int Created;
    public Demo(int c) { Created = c; }
}

class Program
{
    static void Main()
    {
        var d = new Demo(7);
        Console.WriteLine(Demo.Max + ", " + d.Created);
    }
}

الأسئلة الشائعة

هل درس «الثوابت والحقول readonly» مجاني؟

نعم — نص درس «الثوابت والحقول readonly» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «الثوابت والحقول readonly»؟

ميّزوا بين const وstatic readonly تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الثوابت والحقول readonly»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الأساليب والحقول الساكنة
  2. الفئات الساكنة للأدوات المساعدة
  3. الثوابت والحقول readonly
  4. التصميم الساكن مقابل تصميم النسخ
← العودة إلى C# Academy