我希望使某些功能尽可能通用。
在我的MVC应用程序中,我必须将许多复杂的IEnumerable对象转换为SelectLists以进行下拉显示等。
首先,我创建了一个静态List类,其中包含每个复杂对象的转换方法。这相当于很多代码。我接下来开始使用linq语句进行转换:
var list = (from o in SessionTypes select new SelectListItem { Value = o.ID.ToString(), Text = o.Title }).ToList();
但同样,在接受许多此类转换时仍然需要大量代码。
我终于找到了类似的东西:
public IEnumerable<SelectListItem> ToSelectList<T>(IEnumerable<T> enumerable, Func<T, string> value, Func<T, string> text)
{
return enumerable.Select(f => new SelectListItem()
{
Value = value(f),
Text = text(f),
});
}
为了更容易使用,我把它作为一种扩展方法:
public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, string> value, Func<T, string> text)
{
return enumerable.Select(f => new SelectListItem()
{
Value = value(f),
Text = text(f),
});
}
所以现在,我所要做的就是:
var list = SessionTypes.ToSelectList(o => o.ID.ToString(), o => o.Title) as List<SelectListItem>;
我也有类似的方法,例如.ToDictionary。
这是否过度使用扩展方法?我担心我在扩展方法中隐藏了太多代码,这可能会扭曲我的模型,使用linq转换来提高透明度会更好吗?
答案 0 :(得分:4)
您可以直接将IDictionary<,>
绑定到DropDownList
DataSource
,在WebForms中,您需要指定DataValueField="Key"
和DataTextField="Value"
等映射。考虑到为什么不只是使用LINQ ToDictionary()
方法?
dropDownList.DataValueField = "Key";
dropDownList.DataTextField = "Value";
dropDownList.DataSource =
SessionTypes.ToDictionary(k => k.ID.ToString(),
v => v.Title);
答案 1 :(得分:2)
这是扩展方法的完全可接受的用法。
只要他们被描述性地命名并按照他们所说的做就不应该有问题。
答案 2 :(得分:2)
本指南来自C#深度:
“如果扩展方法适用于所有人,则合理有效 扩展类型的实例。如果它只适用于某些 情况,然后明确表示该方法不是类型的一部分 将其作为“正常”静态方法“。
只要您在IEnumerable类型的所有实例上公开此扩展方法,那么您就可以了。
在较轻松的说明中,我宁愿将扩展方法称为ToSelectListItem
,而不是ToSelectList
,以便为最终用户明确说明。这也是我个人的偏好。