Use ForEach extension in Razor

左心房为你撑大大i 提交于 2019-12-06 03:59:44

问题


I am using an IEnumerable extension to loop through a collection and also get its index:

@Model.ForEach((card, i) => {
  @<li class="c@(i)">@card.Text</li>;
})

The ForEach extension is the following:

public static void ForEach<T>(this IEnumerable<T> source, Action<T, Int32> action) {

  Int32 i = 0;
  foreach (T item in source) {
    action(item, i);
    i++;
  }

} // ForEach

But when I try to compile it I get the following error message:

Argument 1: cannot convert from 'void' to 'System.Web.WebPages.HelperResult'

How can I solve this? Do I need a new extension?


回答1:


Your problem is that Razor expects your ForEach method to return a value, such as MvcHtmlString.

Also, you cannot simply expect Razor to translate the body of your foreach clause to work with your Action delegate. There is a way to get this to work, but it's not as pretty. I'd suggest using the @for(...) clause as James suggested if you want to use the standard razor syntax.

However, here's an implementation that does work:

public static MvcHtmlString ForEach<T>(this IEnumerable<T> source, Func<T, Int32, string> selector)
{
    return new MvcHtmlString(String.Join("\n", source.Select(selector)));
}

Usage:

@Model.ForEach((card, i) =>
{
    return "<li class=c" + i + ">" + card.Text + "</li>";
})



回答2:


This works, but it feels hackish:

public static HelperResult ForEach<T>(this IEnumerable<T> source, Func<T, int, Func<TextWriter, HelperResult>> action) {
  return new HelperResult((writer) => {
    int i = 0;
    foreach (T item in source) {
      action(item, i)(writer).WriteTo(writer);
      i++;
    }
  });
}

@Model.ForEach((card, i) => 
    @<li class="c@(i)">@card.Text</li>
)


来源:https://stackoverflow.com/questions/23498283/use-foreach-extension-in-razor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!