Creating a generic select list generating method of type T
.net, asp.net-mvc-3, c#
Solution
You can define this using Reflection to take property value by name, but I think more elegant and flexible to use Func. Change your method to:
public IEnumerable<SelectListItem> CreateSelectList<T>(IList<T> entities, Func<T, object> funcToGetValue, Func<T, object> funcToGetText)
{
return entities
.Select(x => new SelectListItem
{
Value = funcToGetValue(x).ToString(),
Text = funcToGetText(x).ToString()
});
}
And then you can use it by this way:
viewModel.Categories = _formServices.CreateSelectList(categories, x => x.Id, x => x.Name);
Problem
I was wondering how I might be able to create a re-usable method that creates select lists based on method arguments? I was thinking something like below: ``` public IEnumerable<SelectListItem> CreateSelectList(IList<T> entities, T value, T text) { return entities .Select(x => new SelectListItem { Value = x.value.ToString(), Text = x.text.ToString() }); } ``` I think I have it a bit backwards though. I'm unsure how to call a method like this, when I call it with an IList of Category for the first argument the compiler complains that it cannot assign type Category to type T? Also, how would I insert the method arguments into the lambda? Any help appreciated! Code I'm trying to use to call it (which is wrong, but you get the idea) ``` viewModel.Categories = _formServices.CreateSelectList(categories, Id, Name); ``` Code I'm trying to make more generic and reusable: ``` viewModel.Categories = categories .Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Name }); ``` Edit For Answer Credit goes to @Pavel Backshy for working answer. I wanted to edit in an extension I made to his answer in case it helps anybody! The extension just adds a .Where clause into the mix: ``` public IEnumerable<SelectListItem> CreateSelectListWhere<T>(IList<T> entities, Func<T, bool> whereClause, Func<T, object> funcToGetValue, Func<T, object> funcToGetText) { return entities .Where(whereClause) .Select(x => new SelectListItem { Value = funcToGetValue(x).ToString(), Text = funcToGetText(x).ToString() }); } ```