سؤال

ولقد لاحظت تصرفات غريبة لقرار الزائد.

ونفترض أن لدي الطريقة التالية:

public static void DoSomething<T>(IEnumerable<T> items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}

والآن، وأنا أعلم أن هذا الأسلوب غالبا ما يتم استدعاؤها مع عدد قليل من الحجج واضحة، وذلك لراحة أضيف هذا الحمل الزائد:

public static void DoSomething<T>(params T[] items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(params T[] items)");
}

والآن أحاول أن استدعاء هذه الأساليب:

var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");

ولكن في كلتا الحالتين، ويسمى الزائد مع params. كنت أتوقع الزائد IEnumerable<T> ليتم استدعاؤها في حالة وجود List<T>، لأنه يبدو أفضل مباراة (على الأقل بالنسبة لي).

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

هل كانت مفيدة؟

المحلول

والقسم 7.4.3 من مواصفات C # 3.0 هو بت ذات الصلة هنا. في الأساس يتم توسيع صفيف معلمة، لذلك كنت مقارنة:

public static void DoSomething<T>(T item)

و

public static void DoSomething<T>(IEnumerable<T> item)

ويستدل على T للمباراة الأولى التي List<string> ويستدل على T للمباراة الثانية التي string.

والآن النظر في التحويلات المعنية عن حجة لنوع المعلمة - في أول واحد انها List<string> إلى List<string>. في المجموعة الثانية انها List<string> إلى IEnumerable<string>. تحويل الأول هو أفضل من الثاني وفقا للقواعد في 7.4.3.4.

وبت متوقع هو نوع الاستدلال. إذا كنت تأخذ هذا من المعادلة، وأنها ستعمل كما تتوقع أن:

var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");

وعند هذه النقطة، هناك عضو واحد فقط وظيفة قابلة للتطبيق في كل مكالمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top