إنشاء منشئات الفئة وإنشاء مثيل للكائنات

مكتمل

بالإضافة إلى خصائص الفئة وأساليبها، تتضمن تعريفات الفئة الدالات الإنشائية المستخدمة لتهيئة كائنات جديدة (مثيلات الفئة).

منشئات الفئة

الدالة الإنشائية للفئة هي أسلوب بنفس اسم نوعه (تستخدم أساليب الدالة الإنشائية نفس اسم الفئة).

هناك نوعان من الدالات الإنشائية للفئة:

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

منشئات الفئة هي منشئات المثيل بشكل افتراضي.

بناء جملة منشئ المثيل

يتم الإعلان عن منشئ مثيل باستخدام نفس اسم الفئة ولا يتضمن نوع الإرجاع. يمكن أن يتضمن توقيع أسلوب المنشئ معدل وصول اختياري واسم الأسلوب وقائمة المعلمات الخاصة به. لا تتضمن تواقيع أسلوب الدالة الإنشائية نوع الإرجاع.

يوضح المثال التالي منشئ بسيط لفئة تسمى Person:


public class Person
{
    public Person()
    {
        // Field initialization and constructor logic goes here.

    }

    // Remaining implementation of Person class.
}

يمكن أن تحتوي الفئات على أكثر من منشئ واحد. عندما تحتوي الفئة على أكثر من منشئ واحد، عادة ما تأخذ الدالات الإنشائية وسيطات مختلفة.

يوضح المثال التالي فئة تسمى Person مع اثنين من الدالات الإنشائية.


public class Person
{

    public Person()
    {
        // Field initialization and constructor logic goes here.
        string name = "Person One";
        Console.WriteLine($"Person created: {name}");

    }

    public Person(string fName, string lName)
    {
        string name = fName + " " + lName;

        Console.WriteLine($"Person created: {name}");
   }

   // Remaining implementation of Person class.
}

إنشاء مثيل للكائنات باستخدام منشئات الفئة

عند إنشاء مثيل كائن باستخدام الكلمة الأساسية new، يستدعي وقت تشغيل .NET منشئ المثيل المقترن في تعريف الفئة، ويخصص الذاكرة للكائن.

في القصاصة البرمجية التالية، تحدد فئة Person منشئ مثيل بسيط. تتضمن فئة Program أسلوب Main يستخدم عامل التشغيل new لإنشاء مثيل Person باسم person1. يستدعي وقت التشغيل الدالة الإنشائية Person مباشرة بعد تخصيص الذاكرة للكائن الجديد.


public class Person
{
    public Person()
    {
        // Field initialization and constructor logic goes here.

    }
}

static class Program
{
    // the Main method is the entry point of the program.
    static void Main()
    {
        Person person1 = new Person();
    }
}

الدالات الإنشائية ذات المعلمات وبدونها

تسمى الدالة الإنشائية التي لا تأخذ أي معلمات الدالة الإنشائية بلا معلمات. يستدعي وقت التشغيل الدالة الإنشائية بدون معلمات عند إنشاء مثيل لعنصر باستخدام عامل التشغيل new ولا يتم توفير وسيطات للمنشئ.

ملاحظه

ما لم تكن الفئة ثابتة، يتم إعطاء الفئات بدون منشئات منشئ بدون معلمات عامة بواسطة المحول البرمجي C# لتمكين إنشاء مثيل للفئة.

غالبا ما تحدد الفئات الدالات الإنشائية التي تأخذ المعلمات. يجب استدعاء الدالات الإنشائية التي تأخذ المعلمات باستخدام عامل التشغيل new أو عبارة أساسية. يمكن للفئات تعريف منشئ واحد أو أكثر.

تعرض القصاصة البرمجية التالية فئة تسمى Person بثلاثة منشئات:


public class Person
{

    public Person()
    {
        // Field initialization and constructor logic goes here.

        Console.WriteLine("An instance of the Person class is being instantiated without name or age parameters.");
    }

    public Person(string name)
    {
        // Field initialization and constructor logic goes here.

        Console.WriteLine($"An instance of the Person class is being instantiated using a name ({name}) parameter.");
    }

    public Person(string name, int age)
    {
        // Field initialization and constructor logic goes here.

        Console.WriteLine($"An instance of the Person class is being instantiated using name ({name}) and age ({age}) parameters.");
    }
}

static class Program
{
    // the Main method is the entry point of the program.
    static void Main()
    {
        Person person1 = new Person();
        Person person2 = new Person("Person Two");
        Person person3 = new Person("Person Three", 30);
    }
}

فئات بدون منشئات

إذا لم يكن للفئة منشئات مثيل صريحة، يوفر C# منشئ بدون معلمات يمكنك استخدامه لإنشاء مثيل لتلك الفئة، كما يظهر المثال التالي:


public class Person
{
    public int age;
    public string name = "unknown";
}

class Example
{
    static void Main()
    {
        var person = new Person();
        Console.WriteLine($"Name: {person.name}, Age: {person.age}");
        // Output:  Name: unknown, Age: 0
    }
}

يقوم هذا المنشئ بتهيئة حقول المثيل وخصائصه وفقا للمهيئات المقابلة. إذا لم يكن للحقل أو الخاصية أي تهيئة، يتم تعيين قيمته إلى القيمة الافتراضية لنوع الحقل أو الخاصية. إذا قمت بتعريف منشئ مثيل واحد على الأقل في فئة، فإن C# لا يوفر منشئا بلا معلمات.

تهيئة بيانات الفئة باستخدام معلمات الدالة الإنشائية

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

تعرض القصاصة البرمجية التالية فئة تسمى Person مع المنشئات التي تهيئ حقول personNamepersonAge:


public class Person
{
    public string personName;
    public string personAge;

    public Person()
    {
        // Field initialization and constructor logic goes here.
        personName = "unknown";
        personAge = "unknown";
    }

    public Person(string name)
    {
        // Field initialization and constructor logic goes here.
        personName = name;
        personAge = "unknown";
    }

    public Person(string name, int age)
    {
        // Field initialization and constructor logic goes here.
        personName = name;
        personAge = age.ToString();
    }
}

static class Program
{
    // the Main method is the entry point of the program.
    static void Main()
    {
        Person person1 = new Person();
        Person person2 = new Person("Person Two");
        Person person3 = new Person("Person Three", 30);

        Console.WriteLine($"Person 1 Name: {person1.personName} Age: {person1.personAge}");
        Console.WriteLine($"Person 2 Name: {person2.personName} Age: {person2.personAge}");
        Console.WriteLine($"Person 3 Name: {person3.personName} Age: {person3.personAge}");
    }
}

في المثال السابق، يتم تعريف فئة Person بثلاثة منشئات. تقوم الدالة الإنشائية الأولى بتهيئة حقول personNamepersonAge إلى "unknown". يقوم المنشئ الثاني بتهيئة حقل personName إلى القيمة التي تم تمريرها في المعلمة name وحقل personAge إلى "unknown". يقوم المنشئ الثالث بتهيئة حقلي personNamepersonAge إلى القيم التي تم تمريرها في معلمات nameage، على التوالي.

نظرا لأن الحقول عامة، يمكن الوصول إليها مباشرة من أسلوب Main. عند تشغيل التعليمات البرمجية، يتم إنشاء الإخراج التالي:


Person 1 Name: unknown Age: unknown
Person 2 Name: Person Two Age: unknown
Person 3 Name: Person Three Age: 30

تعريفات نص التعبير

إذا كان يمكن تنفيذ الدالة الإنشائية كبيان واحد، يمكنك استخدام تعريف نص تعبير لتعيين معلمة إلى عضو فئة عند تنفيذ الدالة الإنشائية.

على سبيل المثال، تقوم الدالة الإنشائية التالية بتهيئة حقل modelName بالقيمة التي تم تمريرها إلى المعلمة model:


public class Car
{
    public string modelName;

    public Car(string model) => modelName = model;
    
}

تحتوي فئة Car على حقل عام واحد، modelName، وهو من النوع string. يهدف حقل modelName إلى تخزين اسم طراز السيارة.

تتضمن فئة Car أيضا منشئا يأخذ معلمة سلسلة واحدة تسمى model. يستخدم الدالة الإنشائية تعريف نص التعبير (الذي يشير إليه بناء الجملة =>) لتهيئة حقل modelName بالقيمة التي تم تمريرها إلى المعلمة model. وهذا يعني أنه عند إنشاء مثيل لكائن Car جديد، يتم تعيين حقل modelName إلى القيمة المتوفرة كوسيطة للمنشئ.

كما يوحي المصطلح التعبير، فإن الجانب الأيمن من عامل تشغيل => هو تعبير ولا يقتصر على عبارة تعيين بسيطة. يمكن أن يكون التعبير أي تعبير C# صالح يرجع قيمة.

يوضح مقتطف التعليمات البرمجية التالي كيفية تنفيذ تعريف نص تعبير يقوم بإجراء عملية حسابية بسيطة:


public class Employee
{
    public int Salary;

    public Employee() { }

    public Employee(int annualSalary) => Salary = annualSalary;

    public Employee(int weeklySalary, int numberOfWeeks) => Salary = weeklySalary * numberOfWeeks;
}

يمكن إنشاء هذه الفئة باستخدام أي من العبارات التالية:


Employee e1 = new Employee(30000);
Employee e2 = new Employee(500, 52);

الدالات الإنشائية الثابتة

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

تعرض القصاصة البرمجية التالية إصدارا محدثا من فئة Person التي تنفذ حقولا ثابتة ومنشئا ثابتا:


public class Person
{
    public string personName;
    public string personAge;

    // Static field
    public static string defaultName;
    public static string defaultAge;

    // Static constructor
    static Person()
    {
        // Static field initialization
        defaultName = "unknown";
        defaultAge = "unknown";
    }

    public Person()
    {
        // Field initialization and constructor logic goes here.
        personName = defaultName;
        personAge = defaultAge;
    }

    public Person(string name)
    {
        // Field initialization and constructor logic goes here.
        personName = name;
        personAge = defaultAge;
    }

    public Person(string name, int age)
    {
        // Field initialization and constructor logic goes here.
        personName = name;
        personAge = age.ToString();
    }
}

تحتوي فئة Person المحدثة على حقلي مثيل، personNamepersonAge، وكلاهما من نوع string. تخزن هذه الحقول اسم الشخص وعمره، على التوالي.

تعرف الفئة أيضا حقلين ثابتين، defaultName و defaultAge، أيضا من النوع string. تتم مشاركة الحقول الثابتة بين جميع مثيلات الفئة ويتم تهيئتها مرة واحدة فقط. في هذه الحالة، يتم استخدام الحقول الثابتة لتوفير القيم الافتراضية لحقول personNamepersonAge.

الدالة الإنشائية الثابتة static Person() مسؤولة عن تهيئة الحقول الثابتة. يقوم بتعيين defaultName إلى "unknown"defaultAge إلى "unknown". يتم استدعاء الدالة الإنشائية الثابتة تلقائيا قبل إنشاء أي مثيلات للفئة أو الوصول إلى أي أعضاء ثابتين.

تتضمن فئة Person ثلاثة منشئات المثيلات:

public Person() المنشئ بلا معلمات تهيئة حقول personNamepersonAge مع قيم الحقول الثابتة defaultNamedefaultAge. وهذا يعني أنه إذا لم يتم توفير وسيطات عند إنشاء كائن Person، استخدام القيم الافتراضية "unknown" لكل من الاسم والعمر.

يأخذ public Person(string name) المنشئ معلمة واحدة، name، ويهيئ حقل personName بهذه القيمة. تتم تهيئة الحقل personAge بقيمة الحقل الثابت defaultAge. يسمح هذا المنشئ بإنشاء كائن Person باسم محدد أثناء استخدام العمر الافتراضي.

يأخذ public Person(string name, int age) الإنشائية معلمتين، nameage. يقوم بتهيئة الحقل personName بقيمة المعلمة name وحقل personAge مع تمثيل سلسلة معلمة العمر. يسمح هذا المنشئ بإنشاء كائن Person مع كل من name محددة age.

خصائص الدالات الإنشائية الثابتة

تحتوي الدالات الإنشائية الثابتة على الخصائص التالية:

  • لا يأخذ المنشئ الثابت معدلات الوصول أو لديه معلمات.

  • يمكن أن تحتوي الفئة على منشئ ثابت واحد فقط.

  • لا يمكن توريث الدالات الإنشائية الثابتة أو تحميلها بشكل زائد.

  • لا يمكن استدعاء الدالة الإنشائية الثابتة مباشرة، والمقصود فقط أن يتم استدعاؤها بواسطة وقت تشغيل اللغة الشائعة (CLR). يتم استدعاؤه تلقائيا.

  • لا يتحكم المستخدم في وقت تنفيذ الدالة الإنشائية الثابتة في البرنامج.

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

  • إذا لم توفر منشئا ثابتا لتهيئة الحقول الثابتة، تتم تهيئة جميع الحقول الثابتة إلى قيمتها الافتراضية.

  • إذا طرح منشئ ثابت استثناء، لا يستدعيه وقت التشغيل مرة ثانية، ويظل النوع غير متسلسل طوال مدة بقاء مجال التطبيق. الأكثر شيوعا، يتم طرح استثناء TypeInitializationException عندما يكون المنشئ الثابت غير قادر على إنشاء مثيل لنوع أو لاستثناء غير معالج يحدث داخل منشئ ثابت. بالنسبة إلى المنشئات الثابتة التي لم يتم تعريفها بشكل صريح في التعليمات البرمجية المصدر، قد يتطلب استكشاف الأخطاء وإصلاحها فحص التعليمات البرمجية للغة الوسيطة (IL).

  • يمنع وجود منشئ ثابت إضافة سمة نوع BeforeFieldInit. هذا يحد من تحسين وقت التشغيل.

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

  • يستدعي وقت التشغيل منشئا ثابتا لا يزيد عن مرة واحدة في مجال تطبيق واحد. يتم إجراء هذا الاستدعاء في منطقة مؤمنة استنادا إلى نوع معين من الفئة. لا توجد حاجة إلى آليات تأمين إضافية في نص الدالة الإنشائية الثابتة.

ملاحظه

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