1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Razor:

@Model.Each(@<li>Item @item.Index of @(Model.Count() - 1): @item.Item.Title</li>)


Spark:

<li each="item in Model">${itemIndex} of ${Model.Count() - 1}: ${item.Title}</li>


How we use HtmlTags:

var count = Items.Count() - 1;
Tags.UnorderedList
    .Nest(Items.Select((item, index) => Tags.LI.Text(string.Format("{0} of {1}: {2}", index, count, item.Title)));


I'd argue that Spark is the most readable solution, but HtmlTags could be the easiest to refactor/resuse.

It seems odd to me that LINQ's Select method has an index overload but the Razor designers overlooked that overload in their "select" implementation.