2010-03-05 99 views
13

我是相當新的(好的,真的是新的)泛型,但我喜歡它們的想法。我會在視圖中有幾個下拉列表,我想一個通用的方式,採取對象的列表並將其轉換成的SelectListItems如何編寫泛型IEnumerable <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 2010-03-05 20:05:01

+1

我怎麼會這樣稱呼,特別是使用'selected'代表? – Dan 2010-03-05 20:12:10

+0

非常好的解決方案! – Samuel 2012-07-30 17:33:04

3

爲了書面這項工作,你的類型T將需要實現一些接口,它提供了NameId屬性:

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

這是在您的擴展方法中使用NameId屬性所必需的...您可以改爲提供接收這些屬性的其他方法(即:傳遞代理),但可能會或不會不會增加您場景中的維護成本。

+0

朋友,用這種方法,我怎麼會用它 ?看起來比其他答案更清潔。謝謝 ! – 2011-12-20 18:57:19

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委託(根據Bruno的答案) - OrderBy子句中的item.Name引用當前不會編譯。 – itowlson 2010-03-05 19:33:10

+0

嗯,我想把這個和下一個問題都標記爲答案:)。兩者都是我正在尋找的! – Dan 2010-03-05 19:41:40

+0

@itowlson - 謝謝,我錯過了那一個。 – 2010-03-05 19:43:40

相關問題