2010-03-05 24 views
13

Ben jeneriklere oldukça yeni (Tamam yeni) Tamam ama ben bu fikirleri seviyorum. Ben bir görünümde birkaç açılır listeleri sahip olacağım ve ben nesnelerin listesini alıp Şu an hangi SelectListItemsGeneric IEnumerable <SelectListItem> uzantısı yöntemi nasıl yazılır

listesine dönüştürmek için genel bir yol istiyorum:

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

:

Sorun şu nesneler İşte SelectListItem

ait Text mülkü temsil farklı alanlara sahip olarak her açılır için bu kodu tekrarlamak gerekiyordu, ben başarmak istiyorum olan şey

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 :(
} 
Bu yazılı olarak çalışmak için Amacıyla

cevap

20

Eh, böyle bir şey yapabileceğini: bu yöntemle,

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

Bunu iptal etmek zorunda kaldınız, ToSelectListItems :) – Dan

+1

Bunu nasıl yapmalıyım ve özellikle 'seçilmiş' temsilci kullanmalıyım? – Dan

+0

Çok hoş bir çözüm! – Samuel

3

, senin tipin TName ve Id özellikleri sağlayan bazı arabirim uygulamak gerekir: yerinde Bununla

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

, yapabileceğiniz:

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

Bu, uzantı yönteminizdeki Name ve Id özelliklerini kullanmak için gereklidir ... Bunun yerine, bunları almak için farklı bir yol (yani: geçen delegeler) sağlayabilir, ancak olabilir veya ay senaryoda bakım maliyetini artırmaz.

+0

Arkadaşa, nasıl olur kullan? Diğer cevaplardan daha temiz görünüyor. Teşekkürler ! –

8

Karşılaştırmaları ve özellik alımını yapmak için temsilcilerden geçebilirsiniz. Böyle bir şey:

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

Sonra şöyle kullanmak olacaktır:

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

Ayrıca bir getName temsilcisine de gereksiniminiz var (her Bruno'nun cevabı için) - OrderBy deyimindeki item.Name başvurusu şu anda derlenmiyor. – itowlson

+0

Hmm, Hem bu hem de sonraki soruları cevap olarak belirtmek istiyorum :). Her ikisi de tam olarak aradığım şey! – Dan

+0

@itowlson - teşekkürler, onu özledim. –

İlgili konular