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


Answers

عندما يقوم الزائد الأسلوب عادة بتنفيذ نفس الشيء مع عدد مختلف من الوسيطات ثم سيتم استخدام الافتراضيات.

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

اعتدت اختياري مرة أخرى في بلدي VB6 أيام ومنذ ذلك الحين غاب عنه، وسوف يقلل الكثير من شمل تكرار الازدواجية في C #.

Question

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

على سبيل المثال شيء مثل فئة FileStream لديه حوالي خمسة عشر منشئات مختلفة والتي يمكن تقسيمها إلى منطقية 'الأسر' على سبيل المثال تلك أدناه من سلسلة، تلك من SafeFileHandle وتلك من 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);

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

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




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

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




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

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

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

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




وسوف يكون بالتأكيد باستخدام ميزة المعلمات الاختيارية من 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)
{
}

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