سؤال

إليك طريقة بسيطة مع ملف foreach عقدة:

IEnumerable<XElement> FieldsToXElements(object instance)
{
    var fieldElements = new List<XElement>();

    foreach (var field in instance.GetType().GetFields(instance))
    {
        fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
    }

    return fieldElements;
}

نوع من القبيح. إذا كان هناك بعض المشغل في LINQ وهذا يعني "افعل شيئًا" (على سبيل المثال ، Action لكل تم اختياره في عبارة LINQ) ، سيبدو أجمل وأكثر ترويسًا:

IEnumerable<XElement> FieldsToXElements(object instance)
{
    var fieldElements = new List<XElement>();

    from field in instance.GetType().GetFields(instance))
    let name = field.Name
    let value = field.GetValue(instance)
    do fieldElements.Add(new XElement(name, value));

    return fieldElements;
}

أدرك أن هذا شخصي ، ورأيتي فقط. بالنسبة لحلقة foreach التي تحتوي على سطر واحد يستدعي ببساطة طريقة ، "do"المشغل منطقي ، في رأيي. لكنني أتساءل عما إذا كان أي شخص في MS قد فكر في نفس الشيء. هل تم التخطيط لمشغل LINQ في أي إصدارات قادمة (على سبيل المثال إلى جانب ظهور C# 4.0)؟

إليك مثال آخر ، مع مسند ، حيث الوهمية do المشغل سيجعل الكود يبدو أنظف. هذه:

IEnumerable<XElement> FieldsToXElements
    (object instance, Func<FieldInfo, bool> predicate)
{
    var fieldElements = new List<XElement>();

    foreach (var field in instance.GetType().GetFields(instance).Where(predicate))
    {
        fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
    }

    return fieldElements;
}

مقابل هذا:

IEnumerable<XElement> FieldsToXElements
    (object instance, Func<FieldInfo, bool> predicate)
{
    var fieldElements = new List<XElement>();

    from field in instance.GetType().GetFields(instance))
    let name = field.Name
    let value = field.GetValue(instance)
    where predicate(field)
    do fieldElements.Add(new XElement(name, value));

    return fieldElements;
}
هل كانت مفيدة؟

المحلول

لا ، لا أتوقع أي مباشرة لغة Suport (أي داخل بناء جملة الاستعلام) في أي وقت قريب.

يبدو أنك تقصد الأسطورية ForEach طريقة التمديد ؛ تافهة للإضافة ، لكن إريك ليبرت علق عدة مرات حول التقاطع بين الكود الوظيفي الخالي من التأثير و Action<T> مع الآثار الجانبية. على وجه الخصوص ، فإن أشجار التعبير C# 3.0 / .NET 3.5 رديئة في الآثار الجانبية (مما يجعل دعم Lambda الكامل أمرًا صعبًا). جانب وقت التشغيل أفضل بكثير في .NET 4.0, ، لكن من غير الواضح في الوقت الحالي كم من هذا سيجعله في اللغة (برنامج التحويل البرمجي Lambda) في C# 4.0.

كل ما تحتاجه (لإصدار المندوب) هو:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{   // note: omitted arg/null checks
    foreach(T item in source) { action(item); }
}

ثم من أي استعلام يمكنك استخدامه ببساطة .ForEach(x => /* do something */).

نصائح أخرى

للحصول على مثالك المحدد (ملء أ List<XElement>) ، سأفعل ذلك بهذه الطريقة.

IEnumerable<XElement> FieldsToXElements(object instance)
{
  List<XElement> fieldElements =
  (
    from field in instance.GetType().GetFields(instance))
    let name = field.Name
    let value = field.GetValue(instance)
    select new XElement(name, value)
  ).ToList();  //Another Option is List<T>.AddRange()
  return fieldElements;
}

أيضا: لا تنسى ذلك List<T> تنفذ بالفعل .ForEach<T>(), ، لذلك لاستخدامه ضد أي Enumerable<T>, ، هذا هو كل الرمز الذي تحتاجه.

myEnumerable.ToList().ForEach( x => myAction(x) );

لا أعتقد أن هذا صعب للغاية أو ربما أفتقد شيئًا ...

IEnumerable<XElement> FieldsToXElements(object instance)
{
    return instance.GetType()
                   .GetFields(instance)
                   .Select( f => new XElement( f.Name,
                                               f.GetValue(instance) ) );
}

إذا كنت تبحث ببساطة في استدعاء وظيفة من داخل بيان LINQ الخاص بك ، فيمكنك القيام بذلك بالفعل ، فيمكنك إجراء استدعاء إلى وظيفة في مهمة Let.

var qry = from e in somelist
          let errorcode = DoSomeProcessing(e)
          select e;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top