当我事先不知道对象时,如何构建一个构建MvcHtmlString Breadcrumb路径的递归函数?

时间:2010-09-20 21:17:06

标签: c# asp.net asp.net-mvc lambda

我相信我需要使用一个使用lambda表达式来完成此操作的html帮助器方法。

我正在考虑按照以下方式做点什么:

    public static MvcHtmlString GetCategoryBreadCrumbs<T>(
        this HtmlHelper html,
        IEnumerable<T> currentCat,
        Func<T, T> parentProperty,
        Func<T, string> itemContent)
    {
        var sb = new StringBuilder();
        sb.AppendLine(itemContent(currentCat));
        if (currentCat.parentProperty.Count() > 0)
            sb.AppendLine(GetCategoryBreadCrumbs(html, currentCat.parentProperty, itemContent);

        return MvcHtmlString.Create(sb.ToString());
    }

然后我想把它称之为:

<%: Html.GetCategoryBreadCrumbs(
Model, l => l.parentCategories, 
    l => l.catID, 
    l => l.catName)%>

显然,即使在伪代码级别,我上面的内容也很糟糕。

Lamba / Generic方法如何工作?

1 个答案:

答案 0 :(得分:3)

嗯,我认为您应该考虑将“类别”的递归遍历与面包屑字符串的创建分开。将它们混合在一起,就像您一样,使代码更难理解和维护。通过分离可能发生变化的实现部分,可以使最终结果更容易理解,更不易碎,也不那么难看。

public static IEnumerable<T> GetHierarchy<T>( this T item, Func<T,T> getParent )
{
    while( item != null )
    {
        yield return item;
        item = getParent( item );
    }        
}

现在您可以使用String.Join()完成其余工作:

<%: MvcHtmlString.Create(
      string.Join( " >> ", Model.GetHierarchy( item => item.GetParent() )
                                .Select( item => item.catName ) ) %>

在上面的代码中,我假设GetParent()提供了一种导航到给定对象实例的父级的简单方法。如果此代码在运行时有所不同,您可以使用另一个lambda,也可以创建一个接口来统一具有“父”的不同类型的类。

显然,如果您要在多个视图中生成面包屑字符串,您应该考虑将其包装在帮助器中。