我想知道如何创建一个可重用的方法来创建基于方法参数的选择列表?我在想下面的事情:
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()
});
}
我觉得我有点倒退了。我不确定如何调用这样的方法,当我用类别的IList为第一个参数调用它时编译器抱怨它不能将类型类型分配给类型T?另外,我如何将方法参数插入lambda?任何帮助表示赞赏!
Code I我试图用来调用它(这是错误的,但你明白了)
viewModel.Categories = _formServices.CreateSelectList(categories, Id, Name);
代码我正在尝试制作更通用和可重用的代码:
viewModel.Categories = categories
.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
});
编辑以供回答
感谢@Pavel Backshy获得工作答案。我想编辑一个扩展,我做了他的回答,以防它帮助任何人!扩展只是在混合中添加.Where子句:
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()
});
}
答案 0 :(得分:7)
您可以使用Reflection来定义此属性值,但我觉得使用Func更加优雅和灵活。 将您的方法更改为:
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()
});
}
然后你可以通过这种方式使用它:
viewModel.Categories = _formServices.CreateSelectList(categories, x => x.Id, x => x.Name);
答案 1 :(得分:1)
我找到了Pavel Bakshy的答案,以及你的编辑,包括'whereClause'非常有帮助,以及我想要完成的事情。 沿着同样的路线,我还添加了一个'selectedValue'对象,因为这是我试图做的事情的一部分。 'null'检查用于当列表没有当前选择的值时(即首次加载时)。
编辑:我还使用IEnumerable而不是IList作为我的第一个参数
IEnumerable<SelectListItem> ISelectUtils.CreateSelectList<T>(IEnumerable<T> entities, Func<T, bool> whereClause, Func<T, object> funcToGetValue, Func<T, object> funcToGetText, object selectedValue)
{
return entities
.Where(whereClause)
.Select(x => new SelectListItem
{
Value = funcToGetValue(x).ToString(),
Text = funcToGetText(x).ToString(),
Selected = selectedValue != null ? ((funcToGetValue(x).ToString() == selectedValue.ToString()) ? true : false) : false
});
}