كيف C # مترجم اختيار SelectMany عند ترجمة التعبير LINQ؟

StackOverflow https://stackoverflow.com/questions/422958

  •  05-07-2019
  •  | 
  •  

سؤال

وهناك 4 التوقيعات طاقتها لEnumerable.SelectMany. لجعلها بسيطة، تجاهلنا التوقيعات اثنين مع الباحث حجة. لذلك لدينا 2 التوقيعات لSelectMany:

public static IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector
)

public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TCollection>> collectionSelector,
    Func<TSource, TCollection, TResult> resultSelector
)

وسؤالي هو: كيف C # مترجم اختيار SelectMany عند ترجمة التعبير LINQ إلى طريقة تمديد الاحتجاج

والأساس، وإذا كان هناك عدة من في التعبير LINQ، سيكون هناك SelectMany. ولكن، يبدو أن C # مترجم فقط اختيار التوقيع الثاني. ويستخدم التوقيع الأول أبدا.

        IEnumerable<int> en1 = Enumerable.Range(1, 3);
        IEnumerable<double> en2 = new double[] { 1.0, 3.14 };

        IEnumerable<string> en3 =
            from i1 in en1
            from i2 in en2
            select (i1 * i2).ToString();

        foreach (var i in en3)
        {
            Console.WriteLine(i);
        }

وبمساعدة العاكس، أستطيع أن أرى فوق التعبير LINQ تترجم إلى

en1.SelectMany<int, double, string>(delegate (int i1) {
        return en2;
    }, delegate (int i1, double i2) {
        double CS$0$0000 = i1 * i2return CS$0$0000.ToString();
    })

وفوق سبيل المثال يتضمن 3 أنواع. لذا، فمن المعقول أن حدد التوقيع SelectMany الثاني. ومع ذلك، لأقل من سبيل المثال، وتشارك نوع واحد فقط، فإنه لا يزال يختار التوقيع الثاني.

        IEnumerable<int> en4 =
            from i1 in en1
            from i2 in Enumerable.Range(0, i1)
            select i2;

ويتم ترجمته إلى:

en1.SelectMany<int, int, int>(delegate (int i1) {
        return Enumerable.Range(0, i1);
    }, delegate (int i1, int i2) {
        return i2;
    })

وهكذا، وأنا لا يمكن العثور على القضية التي تترجم LINQ التعبير إلى توقيع SelectMany الأول. هل هناك مثل هذه الحالة؟

إذا لم يتم استخدام التوقيع SelectMany الأول، ثم وجدت فقط لأنه هو BIND من الكائن الدقيق الاحادي الخلية في البرمجة الوظيفية؟

ولعل السؤال يمكن أن يكون: لماذا لدينا 2 تواقيع SelectMany

وشكرا.

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

المحلول

ووفقا لC # المواصفات، فإن المترجم لا تولد مكالمة الزائد إلى الإصدار الأول من SelectMany. النسخة الأولى من SelectMany هو مفيد لتسطيح قائمة من قوائم في قائمة شقة واحدة.

public IEnumerable<string> Example(IEnumerable<IEnumerable<string>> enumerable) {
  return enumerable.SelectMany(x => x);
}

وليس لديها ما يعادل قوي في تعبير استعلام.

وانظر القسم 7.15.2 اللغة المواصفات C # لمزيد من المعلومات.

نصائح أخرى

<اقتباس فقرة>   

وماذا لدينا 2 تواقيع SelectMany؟

وهكذا يمكنني استخدام أول واحد في قانون بلدي.

var orders = Customers.SelectMany(c => c.Orders)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top