2010-03-05 3 views
13

나는 generics에 상당히 새로운 (좋아, 진짜로 새로운) 그러나 나는 그 아이디어를 좋아한다. 내가보기에 몇 드롭 다운 목록을 낳게 될 것 그리고 난 개체의 목록을 가지고 내가 지금 무엇을 가지고 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 :(
} 
이 기록으로 작동하기 위해서는 16,

답변

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

, 당신의 유형 TNameId 특성을 제공하는 몇 가지 인터페이스를 구현해야합니다 : 장소에두고

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

친구, 어떻게 것 그걸 써 ? 다른 답보다 깨끗해 보입니다. 감사 ! –

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

또한 (Bruno의 대답에 따라) getName 대리자가 필요합니다. OrderBy 절의 item.Name 참조는 현재 컴파일되지 않습니다. – itowlson

+0

흠,이 질문과 다음 질문을 답변으로 표시하고 싶습니다. :). 둘 다 내가 찾고있는 것입니다! – Dan

+0

@itowlson - 감사합니다. 나는 그 중 하나를 놓쳤습니다. –

관련 문제