2009-01-24 6 views
11

यहां foreach लूप के साथ एक साधारण विधि है:"डू"/एक्शन LINQ ऑपरेटर के लिए कोई योजना?

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 में कुछ ऑपरेटर थे जिसका अर्थ है "कुछ करें" (उदाहरण के लिए LINQ कथन में चयनित प्रत्येक के लिए Action निष्पादित करें), यह अच्छा लगेगा, अधिक terse:

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; 
} 

मुझे एहसास है कि यह व्यक्तिपरक है, और बस मेरा राय। एक फोरैच लूप के लिए जिसमें एक पंक्ति है जो बस एक विधि का आह्वान करती है, मेरी राय में "do" ऑपरेटर समझ में आता है। लेकिन मैं सोच रहा हूं कि एमएस में किसी ने भी यही बात सोचा है। क्या ऐसे LINQ ऑपरेटर किसी भी आगामी रिलीज में योजनाबद्ध है (उदाहरण के लिए सी # 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; 
} 

उत्तर

15

नहीं, मैं किसी भी प्रत्यक्ष भाषा suport (अर्थात क्वेरी सिंटैक्स के अंदर) किसी भी समय जल्दी ही उम्मीद नहीं है।

ऐसा लगता है जैसे आप पौराणिक ForEach विस्तार विधि का अर्थ है; जोड़ने के लिए तुच्छ, लेकिन एरिक लिपर्ट ने साइड इफेक्ट-फ्री फ़ंक्शनल कोड और साइड इफेक्ट्स के साथ Action<T> के बीच क्रॉस के बारे में कई बार टिप्पणी की है। विशेष रूप से, सी # 3.0/.NET 3.5 अभिव्यक्ति पेड़ साइड-एफफेक्स पर लुसी होते हैं (पूर्ण लैम्ब्डा समर्थन को मुश्किल बनाते हैं)। रनटाइम साइड is much better in .NET 4.0, लेकिन यह इस समय अस्पष्ट है कि इसमें से कितना इसे सी # 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 */) उपयोग कर सकते हैं।

1

मुझे नहीं लगता कि यह बहुत कठिन है या हो सकता है मैं याद कर रहा हूँ कुछ ...

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

कार्य छोटा है। मुझे कोड की "सुंदरता" में अधिक दिलचस्पी है। :) – core

1

तो आप पहले से ही ऐसा कर सकते हैं तो आप बस अपने LINQ बयान के भीतर से एक समारोह बुला पर देख रहे हैं , आप लेट असाइनमेंट में फ़ंक्शन पर कॉल कर सकते हैं।

var qry = from e in somelist 
      let errorcode = DoSomeProcessing(e) 
      select e; 
+0

यहां एकमात्र समस्या है DoSomeProcessing एक Func <>, कोई क्रिया नहीं है <> :) – core

+0

थोड़ा गैर-सुंदर, लेकिन मुश्किल :) – Teejay

3

अपने विशिष्ट उदाहरण के लिए (एक 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)); 
+0

बहुत अच्छा! उस बारे में सोचा नहीं था।यद्यपि मैं इसे केवल थोड़ा करके छोटा कर दूंगा: वापसी (फ़ील्ड से ...)। सूची फ़ील्ड एलिमेंट्स को परिभाषित किए बिना। एक बार फिर धन्यवाद! – core

संबंधित मुद्दे