2010-03-05 15 views
13

लिखने के लिए कैसे मैं जेनेरिक के लिए काफी नया (ठीक है, वास्तव में नया) हूं लेकिन मुझे उनके विचार पसंद हैं। मैं एक दृश्य पर कुछ ड्रॉप-डाउन सूचियों होने जा करने के लिए जा रहा हूँ और मैं वस्तुओं की एक सूची लेने के लिए और यह SelectListItemsजेनेरिक आईनेमरेबल <SelectListItem> एक्सटेंशन विधि

की एक सूची में बदलने का क्या मैं अब के लिए एक सामान्य तरीके चाहते हैं:

public static IEnumerable<SelectListItem> ToSelectListItems(
    this IEnumerable<SpecificObject> items, long selectedId) 
    { 
     return 
      items.OrderBy(item => item.Name) 
      .Select(item => 
        new SelectListItem 
        { 
         Selected = (item.Id == selectedId), 
         Text = item.Name, 
         Value = item.Id.ToString() 
        }); 
    } 

मुसीबत मैं के रूप में वस्तुओं विभिन्न क्षेत्रों कि SelectListItem

यहाँ की Text संपत्ति का प्रतिनिधित्व करते हैं प्रत्येक ड्रॉप-डाउन के लिए कि कोड दोहराने की आवश्यकता होगी, है मैं हासिल करना चाहते हैं क्या है:

public static IEnumerable<SelectListItem> ToSelectListItem<T>(this IEnumerable<T> items, string key, string value, int SelectedId) { 
    // I really have no idea how to proceed from here :(
} 

उत्तर

20

ठीक है, आप कुछ इस तरह कर सकता है:,

public static IEnumerable<SelectListItem> ToSelectListItems(
    this IEnumerable<T> items, 
    Func<T,string> nameSelector, 
    Func<T,string> valueSelector, 
    Func<T,bool> selected) 
{ 
    return items.OrderBy(item => nameSelector(item)) 
      .Select(item => 
        new SelectListItem 
        { 
         Selected = selected(item), 
         Text = nameSelector(item), 
         Value = valueSelector(item) 
        }); 
} 
+0

इसे रद्द करें, ToSelectListItems :) – Dan

+1

मैं इसे कैसे कॉल करूंगा और विशेष रूप से 'चयनित' प्रतिनिधि का उपयोग कैसे करूं? – Dan

+0

बहुत अच्छा समाधान! – Samuel

3

इस लिखित रूप में काम करने के लिए आदेश में, अपने प्रकार T कुछ इंटरफ़ेस जो Name और Id गुण प्रदान करता है को लागू करने की आवश्यकता होगी: जगह में इस के साथ

public interface ISelectable 
{ 
    string Name { get; } 
    int Id { get; } 
} 

, आप कर सकते हैं:

public static IEnumerable<SelectListItem> ToSelectListItems<T>(this IEnumerable<T> items, long selectedId) 
    where T : ISelectable 
{ 
    return 
     items.OrderBy(item => item.Name) 
     .Select(item => 
       new SelectListItem 
       { 
        Selected = (item.Id == selectedId), 
        Text = item.Name, 
        Value = item.Id.ToString() 
       }); 
} 

यह आपकी विस्तार विधि के भीतर Name और Id गुणों का उपयोग करने के लिए आवश्यक है ... इसके बजाय, आप इन्हें प्राप्त करने का एक अलग माध्यम प्रदान कर सकते हैं (यानी: गुजरने वाले प्रतिनिधियों), लेकिन यह हो सकता है आपके परिदृश्य में रखरखाव लागत में वृद्धि नहीं है।

+0

मित्र को इस विधि के साथ, मैं कैसे होगा इसका इस्तेमाल करें ? अन्य उत्तरों की तुलना में क्लीनर दिखता है। धन्यवाद ! –

8

आप तुलना करने और संपत्ति पुनर्प्राप्ति करने के लिए प्रतिनिधियों में पास हो सकते हैं। कुछ इस तरह:

public static IEnumerable<SelectListItem> ToSelectListItem<T>(this IEnumerable<T> items, 
    int selectedId, Func<T,int> getId, Func<T, string> getName, 
    Func<T, string> getText, Func<T, string> getValue) 
{ 
    return 
     items.OrderBy(item => getName(item)) 
     .Select(item => 
       new SelectListItem 
       { 
        Selected = (getId(item) == selectedId), 
        Text = getText(item), 
        Value = getValue(item) 
       }); 
} 

तो फिर तुम यह इतना तरह का प्रयोग करेंगे:

var selected = specificObjects.ToSelectListItem(10, s => s.Id, s=> s.Name, s => s.Name, s => s.Id.ToString()); 
+0

आपको एक GetName प्रतिनिधि (प्रति ब्रूनो का उत्तर) भी चाहिए - आइटम। ऑर्डरबी क्लॉज में वर्तमान संदर्भ संकलित नहीं होगा। – itowlson

+0

हम्म, मैं इस और अगले प्रश्नों को उत्तर के रूप में चिह्नित करना चाहता हूं :)। दोनों ठीक वही हैं जो मैं ढूंढ रहा हूं! – Dan

+0

@itowlson - धन्यवाद, मुझे वह याद आया। –

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