这是否过度使用扩展方法?

时间:2011-11-07 13:38:15

标签: c# asp.net-mvc linq linq-to-objects func

我希望使某些功能尽可能通用。

在我的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转换来提高透明度会更好吗?

3 个答案:

答案 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,以便为最终用户明确说明。这也是我个人的偏好。