شرح - the c# programming language pdf




لماذا لا يمكنني الحصول على طرق ثابتة مجردة في C#؟ (5)

لقد كنت أعمل مع providers بشكل عادل في الآونة الأخيرة ، ولقد صادفت موقفاً مثيراً للاهتمام حيث أردت أن يكون لدي فصل دراسي مجردة له طريقة مجردة ثابتة. قرأت بعض المشاركات حول هذا الموضوع ، وكان من المنطقي ، ولكن هل هناك تفسير واضح وجميل؟


الأساليب المجردة افتراضية ضمنيًا. تتطلب أساليب Abstract مثيل ، ولكن الأساليب الثابتة لا تملك مثيل. لذلك ، يمكن أن يكون لديك طريقة ثابتة في فئة مجردة ، لا يمكن أن تكون مجرد مجردة ثابتة (أو ثابتة مجردة).


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

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

اسمحوا لي أن أعرض مثالا.

مع التعليمة البرمجية التالية:

public class A
{
    public static void Test()
    {
    }
}

public class B : A
{
}

إذا اتصلت بـ B.Test ، على النحو التالي:

class Program
{
    static void Main(string[] args)
    {
        B.Test();
    }
}

ثم الكود الفعلي داخل الأسلوب الرئيسي كما يلي:

.entrypoint
.maxstack 8
L0000: nop 
L0001: call void ConsoleApplication1.A::Test()
L0006: nop 
L0007: ret 

كما ترون ، يتم إجراء المكالمة إلى A.Test ، لأنه كان الفئة A التي عرّفته ، وليس إلى اختبار B.Test ، على الرغم من أنه يمكنك كتابة التعليمات البرمجية بهذه الطريقة.

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

أدرك أن مصممي IL يمكن أن يسمحوا بترجمة الشفرة لاستدعاء B.Test ، وحلّ المكالمة في وقت التشغيل ، لكن ذلك لن يكون ظاهريًا ، إذ لا يزال يتعين عليك كتابة نوع من اسم الفصل هناك.

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

وبالتالي ، لا تتوفر الطرق الثابتة الظاهرية / المجردة في .NET.


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


نحن في الواقع نتجاوز الأساليب الثابتة (في دلفي) ، إنها قبيحة بعض الشيء ، ولكنها تعمل بشكل جيد لتلبية احتياجاتنا.

نحن نستخدمها بحيث يمكن أن تحتوي الطبقات على قائمة بكائناتها المتاحة بدون مثيل الفصل ، على سبيل المثال ، لدينا طريقة تبدو كالتالي:

class function AvailableObjects: string; override;
begin
  Result := 'Object1, Object2';
end; 

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

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

ولهذا يسهل الحفاظ عليه أكثر من وجود تطبيق خادم واحد مختلف لكل عميل.

آمل أن يكون المثال واضحًا.


وقال آخر المستجيب (ماكدويل) أن تعدد الأشكال يعمل فقط على الحالات الكائن. يجب أن تكون مؤهلة ؛ هناك اللغات التي تتعامل مع الطبقات كمثال نوع "فئة" أو "Metaclass". تدعم هذه اللغات تعدد الأشكال لكل من الطريقتين وطبقة (ثابتة).

لا يعد C # ، مثل Java و C ++ قبله ، مثل هذه اللغة. يتم استخدام الكلمة الأساسية static بوضوح للإشارة إلى أن الطريقة مرتبطة بشكل ثابت بدلاً من الديناميكي / الظاهري.





language-design