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

الكلمة static في C#: الأصناف والدوال والحقول والمُنشئات الساكنة

ما معنى static في C#: أعضاء تنتمي إلى النوع لا إلى كائن، وحالة مشتركة بين المثيلات، والدوال والأصناف الساكنة، والمُنشئات الساكنة، وconst مقابل static readonly، وusing static، والخطأ CS0120.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

تعلّم static عضوًا ينتمي إلى النوع لا إلى كائن. حقل المثيل يوجد مرة لكل كائن؛ والحقل الساكن يوجد مرة واحدة، وكفى. دالة المثيل تعمل على كائن (order.Ship())؛ والدالة الساكنة تعمل على النوع (Math.Round(x)) ولا تحتاج إلى كائن إطلاقًا.

الحقول الساكنة: نسخة واحدة مشتركة

أوضح طريقة لرؤية الفرق هي العدّاد. لكل Order معرّفه Id الخاص، لكن عدد الطلبات المنشأة حتى الآن يجب أن يعيش في مكان مشترك.

المخرجات:

Ana #1, Ben #2, Chen #3
Orders created: 3

يُوصل إلى الأعضاء الساكنة عبر اسم النوع: Order.Created لا a.Created. لا تسمح C# بالوصول إلى عضو ساكن عبر مثيل (الخطأ CS0176)، وهذا يجعل واضحًا في موضع الاستدعاء أن القيمة مشتركة.

الدوال الساكنة

لا this للدالة الساكنة. تعمل بمعاملاتها وبالأعضاء الساكنة الأخرى فقط. وهذا يجعلها الشكل الطبيعي للدوال المساعدة التي تحسب شيئًا من مدخلاتها:

المخرجات:

61.38 EUR
7

Main نفسها ساكنة: يستدعيها وقت التشغيل قبل وجود أي كائن.

الخطأ CS0120: شيفرة ساكنة تستخدم أعضاء مثيل

لأن Main ساكنة، يصطدم المبتدئون كثيرًا بهذا الخطأ بمجرد إضافة دالة ثانية:

class Program
{
    int visits;
    void Greet() { Console.WriteLine("Hello"); }

    static void Main()
    {
        Greet();    // error CS0120: An object reference is required for the non-static field, method, or property 'Program.Greet()'
        visits++;   // error CS0120: An object reference is required for the non-static field, method, or property 'Program.visits'
    }
}

لا كائن للدالة الساكنة، فلا توجد visits لتزيدها. حلّان، والصحيح منهما يعتمد على ماهية العضو:

  • العضو بيانات خاصة بكل كائن فعلًا: أنشئ كائنًا واستخدمه. var app = new Program(); app.Greet();
  • العضو لا يحتاج إلى حالة كائن: علّمه static. static void Greet() { ... }

تعليم كل شيء static لإخفاء الخطأ يعمل في برنامج صغير جدًا ويتحوّل إلى حالة عامة في برنامج حقيقي. قرّر بسؤال: هل البيانات تنتمي إلى كائن واحد أم إلى البرنامج كله؟

الاتجاه المعاكس مسموح دائمًا: تستطيع دوال المثيل استدعاء الأعضاء الساكنة بحرية.

الأصناف الساكنة

الصنف المصرّح به static لا يمكن أن يحتوي إلا على أعضاء ساكنة ولا يمكن إنشاء مثيل منه أبدًا. هو مجموعة مسمّاة من الدوال والثوابت.

المخرجات:

77
100
True

يفرض المترجم هذا العقد: عضو المثيل داخل صنف ساكن هو الخطأ CS0708، وnew عليه هو الخطأ CS0712. Math وConsole وFile وPath وEnumerable كلها أصناف ساكنة. ويجب أن تعيش دوال التوسيع أيضًا في صنف ساكن.

المُنشئات الساكنة وstatic readonly

الحقل الساكن الذي تحتاج قيمته إلى أكثر من تعبير واحد يمكن ضبطه في مُنشئ ساكن، يشغّله وقت التشغيل مرة واحدة، قبل أول استخدام للنوع:

المخرجات:

Before first use
ShippingRates initialized
5.50
3
2026-01-01

تعني readonly أنه لا يمكن الإسناد إلى الحقل إلا في مهيّئه أو في المُنشئ الساكن. بعد ذلك لا يمكن إعادة الإسناد إليه، مع أن الكائن الذي يشير إليه قد يبقى قابلًا للتغيير، ولهذا يُكشف القاموس كـ IReadOnlyDictionary.

const مقابل static readonly

كلاهما يعطيك قيمة مسمّاة يتشاركها البرنامج كله، ويختلفان في وقت تثبيت القيمة:

conststatic readonly
تُثبَّت القيمةوقت الترجمةوقت التشغيل، مرة واحدة
الأنواع المسموحةالأرقام، char، bool، string، التعدادات، nullأي نوع
ساكن ضمنيًانعم (لا يمكن كتابة static const)يُصرَّح بأنه ساكن صراحة
يُنسخ في التجميعات المستدعيةنعملا، يُقرأ من الحقل
قابل للاستخدام في حالات switch ووسائط السماتنعملا

صف النسخ مهم للمكتبات: إن صرّح التجميع A بـ public const int MaxItems = 50; واستخدمه التجميع B، يحتوي B على القيمة الحرفية 50. تغيير A إلى 100 لا يفعل شيئًا لـ B حتى يُعاد ترجمة B. للقيم التي قد تتغيّر بين الإصدارات فضّل static readonly.

using static

تستورد الموجّهة using static (C# 6) الأعضاء الساكنة لنوع، فتستدعيها دون اسم النوع:

المخرجات:

Area: 28.27
40

تُقرأ جيدًا في الشيفرة كثيرة الرياضيات. استخدمها باعتدال في غير ذلك: WriteLine أو Parse مجردتان تخفيان النوع الذي تأتي منه الدالة.

الحالة الساكنة والخيوط

الحقل الساكن مشترك بين كل الخيوط في العملية. زيادته من عدة خيوط في الوقت نفسه تُضيع تحديثات، لأن created++ قراءة ثم جمع ثم كتابة، وقد يتداخل خيطان فيها. استخدم Interlocked.Increment(ref created) للعدّادات، أو lock لأي شيء أكبر. تطبيقات الويب هي المكان المعتاد لهذه اللدغة: كل طلب يعمل على خيط ما، فيتشارك جميع المستخدمين حقلًا ساكنًا يحمل "المستخدم الحالي".

دقيقة أخرى: في الصنف العام يحصل كل نوع مُنشأ على حقوله الساكنة الخاصة. Cache<int>.Count وCache<string>.Count حقلان مختلفان.

متى تستخدم static

استخدامات جيدة:

  • دوال مساعدة نقية تحسب نتيجة من وسائطها: التنسيق والتحويلات والتحقق.
  • الثوابت وبيانات البحث للقراءة فقط التي يتشاركها البرنامج.
  • دوال المصنع، مثل TimeSpan.FromMinutes(5) أو Temperature.FromCelsius(21) الخاصة بك.
  • دوال التوسيع.

استخدامات سيئة:

  • الحالة العامة القابلة للتغيير (المستخدم الحالي، سلة التسوق، الإعدادات المتغيّرة). تربط كل شيفرة تلمسها وتجعل الاختبارات تعتمد على بقايا بعضها.
  • أي شيء ستريد استبداله في الاختبارات، مثل الساعة أو قاعدة البيانات أو مرسل البريد. لا يمكن استبدال الاستدعاءات الساكنة بنسخة وهمية؛ أما المثيل الممرّر إلى المُنشئ فيمكن.

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

ماذا تعني static في C#؟

العضو static ينتمي إلى النوع نفسه لا إلى أي كائن. توجد نسخة واحدة من الحقل الساكن مهما كان عدد الكائنات، وتُستدعى الدالة الساكنة على اسم النوع (Math.Max(3, 7)) دون إنشاء مثيل. لا this للدالة الساكنة، فلا تستطيع استخدام حقول المثيل مباشرة.

ما هو الصنف الساكن في C#؟

الصنف المصرّح به static لا يمكن أن يحتوي إلا على أعضاء ساكنة ولا يمكن إنشاء مثيل منه أبدًا (new عليه هو الخطأ CS0712). يجمع دوال مترابطة لا تحتاج إلى حالة كائن، مثل Math وConsole وFile. ويجب التصريح بدوال التوسيع في صنف ساكن.

كيف أصلح "An object reference is required for the non-static field, method, or property"؟

هذا هو الخطأ CS0120: دالة ساكنة، غالبًا Main، تستخدم عضو مثيل. إما أن تنشئ كائنًا وتستدعي العضو عليه (var app = new Program(); app.Run();)، أو تعلّم العضو بـ static إن كان لا يحتاج إلى بيانات خاصة بكل كائن.

ما الفرق بين const وstatic readonly في C#؟

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

متى أستخدم static في C#؟

استخدم static للشيفرة التي لا تعمل إلا على معاملاتها (دوال مساعدة نقية مثل منسّق الأسعار)، وللثوابت والذاكرات المؤقتة العامة فعلًا للبرنامج، ولدوال المصنع. وتجنّب static لأي شيء يحمل حالة خاصة بكل مستخدم أو كل طلب، أو شيء ستريد استبداله في الاختبارات: الحالة المشتركة القابلة للتغيير صعبة الاختبار وغير آمنة بين الخيوط دون أقفال.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن