在c#中是否有一些我没有遇到过的罕见的语言构造(比如我最近学过的一些,一些在Stack Overflow上)来获得表示foreach循环的当前迭代的值?
例如,我目前根据具体情况做这样的事情:
int i = 0;
foreach (Object o in collection)
{
// ...
i++;
}
在c#中是否有一些我没有遇到过的罕见的语言构造(比如我最近学过的一些,一些在Stack Overflow上)来获得表示foreach循环的当前迭代的值?
例如,我目前根据具体情况做这样的事情:
int i = 0;
foreach (Object o in collection)
{
// ...
i++;
}
当前回答
我不相信有一种方法可以获得foreach循环当前迭代的值。数数自己,似乎是最好的办法。
我能问一下,你为什么想知道?
看起来你最有可能做以下三件事中的一件:
1)从集合中获取对象,但在这种情况下,您已经拥有它。
2)为后期处理计算对象…集合有一个可以使用的Count属性。
3)根据对象在循环中的顺序设置它的属性…尽管您可以在将对象添加到集合时轻松地进行设置。
其他回答
我不认为这应该很有效,但它确实有效:
@foreach (var banner in Model.MainBanners) {
@Model.MainBanners.IndexOf(banner)
}
出于兴趣,Phil Haack刚刚在Razor Templated Delegate的上下文中写了一个例子(http://haacked.com/archive/2011/04/14/a-better-razor-foreach-loop.aspx)。
实际上,他编写了一个扩展方法,将迭代包装在一个“IteratedItem”类中(见下文),允许在迭代期间访问索引和元素。
public class IndexedItem<TModel> {
public IndexedItem(int index, TModel item) {
Index = index;
Item = item;
}
public int Index { get; private set; }
public TModel Item { get; private set; }
}
然而,如果你在非razor环境中做一个单独的操作(例如,一个可以作为lambda提供的操作),这在非razor环境中不会是for/foreach语法的可靠替代。
你可以这样写你的循环:
var s = "ABCDEFG";
foreach (var item in s.GetEnumeratorWithIndex())
{
System.Console.WriteLine("Character: {0}, Position: {1}", item.Value, item.Index);
}
之后添加如下结构和扩展方法。
结构和扩展方法封装了Enumerable。选择功能。
public struct ValueWithIndex<T>
{
public readonly T Value;
public readonly int Index;
public ValueWithIndex(T value, int index)
{
this.Value = value;
this.Index = index;
}
public static ValueWithIndex<T> Create(T value, int index)
{
return new ValueWithIndex<T>(value, index);
}
}
public static class ExtensionMethods
{
public static IEnumerable<ValueWithIndex<T>> GetEnumeratorWithIndex<T>(this IEnumerable<T> enumerable)
{
return enumerable.Select(ValueWithIndex<T>.Create);
}
}
如果集合是列表,则可以使用list。IndexOf,如:
foreach (Object o in collection)
{
// ...
@collection.IndexOf(o)
}
我在LINQPad中构建了这个:
var listOfNames = new List<string>(){"John","Steve","Anna","Chris"};
var listCount = listOfNames.Count;
var NamesWithCommas = string.Empty;
foreach (var element in listOfNames)
{
NamesWithCommas += element;
if(listOfNames.IndexOf(element) != listCount -1)
{
NamesWithCommas += ", ";
}
}
NamesWithCommas.Dump(); //LINQPad method to write to console.
你也可以使用string.join:
var joinResult = string.Join(",", listOfNames);