How to write generic IEnumerable<SelectListItem> extension method
Well, you could do something like this:
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)
});
}
You could pass in delegates to do the comparisons, and property retrieval. Something like this:
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)
});
}
Then you would use it like so:
var selected = specificObjects.ToSelectListItem(10, s => s.Id, s=> s.Name, s => s.Name, s => s.Id.ToString());
In order for this to work as written, your type T
will need to implement some interface which provides Name
and Id
properties:
public interface ISelectable
{
string Name { get; }
int Id { get; }
}
With this in place, you can do:
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()
});
}
This is required in order to use the Name
and Id
properties within your extension method... You could, instead, provide a different means of receiving these (ie: passing delegates), but that may or may not increase the maintenance cost in your scenario.