如何判断我是否处于VB.NET中For Each语句的最后一个循环中?
答案 0 :(得分:53)
您可以执行IEnumerator
接口的一般集合For Each
。此界面只有两个方法MoveNext
和Reset
以及一个属性Current
。
基本上,当您在集合上使用For Each
时,它会调用MoveNext
函数并读取返回的值。如果返回的值为True
,则表示集合中存在有效元素,并且通过Current
属性返回元素。如果集合中没有其他元素,MoveNext
函数将返回False
并退出迭代。
从上面的解释可以看出,For Each
显然没有跟踪集合中的当前位置,因此您的问题的答案是短否 强>
但是,如果您仍然希望知道自己是否在集合中的最后一个元素上,则可以尝试以下代码。它检查(使用LINQ)当前项目是否为最后一项。
For Each item in Collection
If item Is Collection.Last Then
'do something with your last item'
End If
Next
答案 1 :(得分:13)
使用For循环而不是ForEach可能会更容易。但是,类似地,你可以在ForEach循环中保留一个计数器,看它是否等于yourCollection.Count - 1
,那么你就是在最后一次迭代中。
答案 2 :(得分:6)
对于foreach,你不可能知道这一点,直到为时已晚(即你已经离开了循环)。
注意,我假设您正在使用只有IEnumerable接口的东西。如果你有一个列表,数组等,那么请按照这里使用.Count或类似的其他答案来查找有多少项目,这样你就可以跟踪你在集合中的位置。
然而,只有IEnumerable / IEnumerator,如果你使用foreach,就没有办法确定是否还有更多。
如果你需要知道这一点,请自己使用IEnumerable,这就是foreach所做的。
以下解决方案适用于C#,但应轻松转换为VB.NET:
List<Int32> nums = new List<Int32>();
nums.Add(1);
nums.Add(2);
nums.Add(3);
IEnumerator<Int32> enumerator = nums.GetEnumerator();
if (enumerator.MoveNext())
{
// at least one value available
while (true)
{
// make a copy of it
Int32 current = enumerator.Current;
// determine if it was the last value
// if not, enumerator.Current is now the next value
if (enumerator.MoveNext())
{
Console.Out.WriteLine("not last: " + current);
}
else
{
Console.Out.WriteLine("last: " + current);
break;
}
}
}
enumerator.Dispose();
这将打印:
not last: 1
not last: 2
last: 3
诀窍是获取当前值的副本,然后要求枚举器尝试继续下一个。如果失败了,你制作的副本确实是最后一个值,否则还有更多。
答案 3 :(得分:2)
简短回答:你不能
答案很长:For Each语句的语义中没有任何内容可以让您识别您是在运行第一个,最后一个还是任何特定的迭代。
For Each内置于IEnumerable和IEnumerable&lt;&gt;接口,行为取决于您正在调用的实现。对于您每次都以不同顺序返回元素的集合,它是有效的,虽然令人困惑。幸运的是,List&lt;&gt;不这样做。
如果您确实需要知道特定的迭代是最后一个,您可以(提前)识别最后一个元素,然后在遇到该元素时采取不同的操作。
更容易检测第一次迭代(例如,通过布尔值),然后执行不同的操作。
一个例子(C#,但VB类似):
StringBuilder result = new StringBuilder();
bool firstTime = true;
foreach(string s in names)
{
if (!firstTime)
{
result.Append(", ");
}
result.Append(s);
firstTime = false;
}
答案 4 :(得分:1)
检查元素是否是容器的最后一个元素。
为什么要这样做?
你可以在循环后放置指令。 (你在最后一个元素上执行)
答案 5 :(得分:1)
使用For循环而不是ForEach会更容易,但是你可以使用
If item.Equals(itemCollection(itemCollection.Count)) Then
...
End If
在ForEach循环内部...假设对象已正确覆盖Equals方法。
这可能比仅仅使用For循环或在单独的变量中跟踪当前索引更加耗费资源。
我不确定这是否是正确的语法,自从我使用VB以来已经很长时间了。
答案 6 :(得分:1)
使用标准的“For Each”循环,你不能。 “for Each”循环的目的是让您专注于数据而不是底层集合。
答案 7 :(得分:1)
我一直回到这篇文章,所以我决定坐下来思考这个问题,我想出了这个:
For Each obj In myCollection
Console.WriteLine("current object: {0}", obj.ToString)
If Object.ReferenceEquals(obj, myCollection.Last()) Then
Console.WriteLine("current object is the last object")
End If
Next
如果您愿意,甚至可以将If...Then...End If
语句缩减为单行。我不确定在每次迭代时调用.Last()
是否会对性能产生很大影响,但是你总是可以将它分配给循环外的一个变量,如果这是让你夜不能寐的话。
答案 8 :(得分:1)
此代码示例可能会有所帮助
For Each item in Collection
If ReferenceEquals(Collection.Item(Collection.Count - 1), item) Then
'do something with your last item'
End If
Next
答案 9 :(得分:0)
如果你被绑定到IEnumerable。你必须进入foreach循环吗?如果没有,你可以在foreach循环之前声明一个变量。在循环期间设置它。然后,在循环之后使用它(如果它不为空)
答案 10 :(得分:0)
好的解决方法很少 假设您正在使用CheckBoxList
然后这段代码示例可能有所帮助:
Dim count As Integer = 0
Dim totalListCount As Integer = CheckBoxList.Items.Count()
For Each li In CheckBoxList.Items
count += 1
// This is the Last Item
If count = totalListCount THEN
// DO Somthing.....
END IF
NEXT
答案 11 :(得分:0)
这是一个简单的事情,我不知道它是否在政治上是正确的,但它的确有效
for each item in listOfThings
if(item = listOfThings.last)then
'you found the last loop
end if
next
答案 12 :(得分:0)
For Each xObj In xColl
If xObj = xColl(xColl.Count) Then ...
Next