[C#] هل يجب عليك الإعلان عن طرق باستخدام الحمولة الزائدة أو المعلمات الاختيارية في C # 4.0؟


Answers

عندما يؤدي الحمل الزائد للطريقة عادة نفس الشيء مع عدد مختلف من الوسيطات ، فسيتم عندئذٍ استخدام الإعدادات الافتراضية.

عندما يؤدي الحمل الزائد للطريقة وظيفة مختلفة على أساس معلماتها ، سيستمر استخدام الحمولة الزائدة.

لقد استخدمت اختياريًا في أيام VB6 الخاصة بي ، ومنذ ذلك الحين فاتته ، سيقلل الكثير من تكرار تعليقات XML في C #.

Question

كنت أشاهد حديث Anders عن C # 4.0 ومعاينة التسلل لـ C # 5.0 ، وجعلني أفكر عندما تكون المعلمات الاختيارية متاحة في C # ما هي الطريقة الموصى بها لإعلان الطرق التي لا تحتاج إلى جميع المعلمات المحددة؟

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

FileStream(string,FileMode);
FileStream(string,FileMode,FileAccess);
FileStream(string,FileMode,FileAccess,FileShare);
FileStream(string,FileMode,FileAccess,FileShare,int);
FileStream(string,FileMode,FileAccess,FileShare,int,bool);

يبدو لي أن هذا النمط من النمط يمكن تبسيطه من خلال وجود ثلاث منشئات بدلاً من ذلك ، واستخدام معلمات اختيارية للمعلمات التي يمكن أن تتعطل ، مما يجعل العائلات المختلفة من المنشئات أكثر تميزًا [ملاحظة: أعرف أن هذا التغيير لن يكون صنعت في BCL ، وأنا أتحدث افتراضيا لهذا النوع من الوضع].

ما رأيك؟ من C # 4.0 سيكون من المنطقي لجعل مجموعات وثيقة الصلة بشكل وثيق من المنشئات والأساليب طريقة واحدة مع المعلمات الاختيارية ، أو هل هناك سبب وجيه للتشبث بالآلية التقليدية الزائدة؟




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

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

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

بالطبع ، هذه ليست إجابة تتعامل مع جميع الجوانب ، لكنني أعتقد أنها تضيف إجابة لم يتم تغطيتها حتى الآن.




سأكون بالتأكيد باستخدام ميزة المعلمات الاختيارية 4.0. يتخلص من سخيفة ...

public void M1( string foo, string bar )
{
   // do that thang
}

public void M1( string foo )
{
  M1( foo, "bar default" ); // I have always hated this line of code specifically
}

... ويضع القيم بشكل صحيح حيث يمكن للمتصل رؤيتها ...

public void M1( string foo, string bar = "bar default" )
{
   // do that thang
}

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

public void M1( string foo )
{
   M2( foo, "bar default" );  // oops!  I meant M1!
}

ﻟم أﻗم ﺑدور ﻣﻊ اﻟﻣُﺟﻣﻊ 4.0 ﺣﺗﯽ اﻵن ، ﻟﮐﻧﻧﻲ ﻟن أﺻُﻌب ﻋﻟﯾﻧﺎ أن أدرك أن اﻟﻣُﺟﻣﻊ ﯾﺻدر ﺑﺑﺳﺎطﺔ اﻟﻌبء اﻟﻣﻔرط ﻟﮐم.




أنا أتطلع إلى المعلمات الاختيارية لأنها تحافظ على ما هي الإعدادات الافتراضية أقرب إلى الطريقة. لذا بدلاً من العشرات من الأسطر للحمولات الزائدة التي تسمي الطريقة "الممددة" ، عليك فقط تحديد الطريقة مرة واحدة ويمكنك رؤية ما هي المعلمات الاختيارية الافتراضية في توقيع الطريقة. أنا أفضل النظر في:

public Rectangle (Point start = Point.Zero, int width, int height)
{
    Start = start;
    Width = width;
    Height = height;
}

بدلا من هذا:

public Rectangle (Point start, int width, int height)
{
    Start = start;
    Width = width;
    Height = height;
}

public Rectangle (int width, int height) :
    this (Point.Zero, width, height)
{
}

من الواضح أن هذا المثال بسيط للغاية ، لكن الحالة في OP مع 5 زائدة ، يمكن أن تزدحم الأشياء بسرعة حقيقية.




يكون لكل من المعلمة الاختيارية ، "التحميل الزائد للطريقة" ميزة خاصة أو غير مؤاتية. يعتمد ذلك على تفضيلاتك للاختيار بينها.

معلمة اختيارية: متوفرة فقط في .Net 4.0. معلمة اختيارية تقليل حجم التعليمات البرمجية. لا يمكنك تحديد وتعديل المعلمة

أساليب overloaded: يمكنك تحديد Out و معلمات ref. سيزداد حجم الشفرة ولكن من السهل فهم طريقة التحميل الزائد.




في حين أنها (من المفترض؟) طريقتان متكافئتان من الناحية النظرية المتاحة لك لنموذج API الخاص بك من الصفر ، للأسف لديهم بعض الاختلاف الدقيق عندما تحتاج إلى مراعاة التوافق مع وقت التشغيل المتأخر لعملائك القدامى في البرية. أشار زميلي (شكراً إلى برنت!) إلى هذا المنصب الرائع: مشكلات إصدار الإصدارات مع الحجج الاختيارية . بعض الاقتباس من ذلك:

كان السبب في إدخال المعلمات الاختيارية إلى C # 4 في المقام الأول هو دعم COM interop. هذا هو. والآن ، نحن نتعرف على الآثار الكاملة لهذه الحقيقة. إذا كان لديك طريقة مع معلمات اختيارية ، فلا يمكنك أبدًا إضافة حمل زائد مع معلمات اختيارية إضافية خوفًا من إحداث تغيير في وقت التجميع. ولا يمكنك مطلقًا إزالة التحميل الزائد الحالي ، حيث كان هذا دائمًا حدث تغيير في وقت التشغيل. تحتاج إلى حد كبير لعلاجها مثل واجهة. ملجأك الوحيد في هذه الحالة هو كتابة أسلوب جديد باسم جديد. لذا كن على علم بذلك إذا كنت تخطط لاستخدام وسائط اختيارية في واجهات برمجة التطبيقات.