القائمة LINQ طريقة التمديد على غرار موازية.؟ [مكررة]

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

سؤال

ممكن مكررة:
LINQ ما يعادل foreach على IEnumerable<T>

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

أكاد أقسم هناك .طريقة ForEach في مكان ما ، ولكن لم يجد ذلك.في هذه الأثناء, لم اكتب بلدي نسخة في حالة من المفيد لأي شخص آخر:

using System.Collections;
using System.Collections.Generic;

public delegate void Function<T>(T item);
public delegate void Function(object item);

public static class EnumerableExtensions
{
    public static void For(this IEnumerable enumerable, Function func)
    {
        foreach (object item in enumerable)
        {
            func(item);
        }
    }

    public static void For<T>(this IEnumerable<T> enumerable, Function<T> func)
    {
        foreach (T item in enumerable)
        {
            func(item);
        }
    }
}

الاستخدام:

myEnumerable.For<MyClass>(delegate(MyClass item) { item.Count++; });

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

المحلول

تسليط المزيد من الضوء على السبب:

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

إذا ، من ناحية أخرى ، ما كنت تريد أن تأخذ المدخلات استدعاء دالة على كل بند بإرجاع نتيجة, LINQ يوفر طريقة من خلال تحديد الأسلوب.

على سبيل المثال التالي رمز المكالمات وظيفة مندوب على كل بند في قائمة العائدين صحيح إذا كان هذا البند هو إيجابي:

    static void Main(string[] args)
    {
        IEnumerable<int> list = new List<int>() { -5, 3, -2, 1, 2, -7 };
        IEnumerable<bool> isPositiveList = list.Select<int, bool>(i => i > 0);

        foreach (bool isPositive in isPositiveList)
        {
            Console.WriteLine(isPositive);
        }

        Console.ReadKey();        
    }

نصائح أخرى

في الواقع ، فإن رد الفعل امتداد إطار من مايكروسوفت للبحوث إضافة هذه الوظيفة.في System.Interactive الجمعية لقد شملت Run() و Do() ملحقات IEnumerable<T>.

هل(العمل) سيتم تنفيذ العمل على كل عنصر العائد مرة أخرى.وهذا مفيد من أجل إضافة تسجيل إلى استعلام linq على سبيل المثال:

var res = GetRandomNumbers(100).Take(10)
      .Do(x => Console.WriteLine("Source  -> {0}", x))
      .Where(x => x % 2 == 0)
      .Do(x => Console.WriteLine("Where   -> {0}", x))
      .OrderBy(x => x)
      .Do(x => Console.WriteLine("OrderBy -> {0}", x))
      .Select(x => x + 1)
      .Do(x => Console.WriteLine("Select  -> {0}", x));

وهذا سوف يؤدي إلى:

Source  -> 96 
Where   -> 96 
Source  -> 25 
Source  -> 8 
Where   -> 8 
Source  -> 79 
Source  -> 25 
Source  -> 3 
Source  -> 36 
Where   -> 36 
Source  -> 51 
Source  -> 53 
Source  -> 81 
OrderBy -> 8 
Select  -> 9 
9 
OrderBy -> 36 
Select  -> 37 
37 
OrderBy -> 96 
Select  -> 97 
97

تشغيل(العمل) مثل حلقة foreach, الذي يعني طي تسلسل تنفيذ العمل.

يمكنك قراءة المزيد عن ذلك هنا: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative.aspx

Rx الإطار يمكن العثور عليها هنا: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

ForEach الأسلوب على List<T> هل هذا.يمكنك التفاف جمع الخاصة بك في قائمة ومن ثم استخدام تلك الدعوة ، ولكن هذا ليس حقا شيء جيد للقيام به.يبدو عليك لفة الخاص بك.

سبق هنا و هناك.

أنا أيضا نعسان أن تذكر ولكن في الأساس،.طريقة ForEach في موضوع واحد التطبيق هو ما يعادل وظيفيا القائمة بالفعل foreach البيان.من ما أفهم الفرق الرئيسي هو أن ForEach يمكن parallized ولكن هذا من شأنه أن يعرض السلوكيات غير المرغوب فيها بسهولة جدا.

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