什么是这个C#'for'循环的VB.NET等价物?

时间:2008-12-19 19:16:51

标签: vb.net

经过两年的C#,我的VB.NET有点生疏了。我有两个列表。我们称它们为originalList和targetList。这是我的C#代码:

for(int i = 0; i<originalList.Count; i++)
{
    bool isMatch = false;
    foreach (string t in targetList)
    {
        if(String.Compare(originalList[i], t, true) == 0)
        {
            isMatch = true;
            break;
        }
    }
    if(isMatch)
    {
        originalList.RemoveAt(i);
        i--;
    }
}

我的VB.NET代码就是这样:

Dim i as Integer
For i = 0 To originalList.Count - 1
    Dim isMatch as boolean = false
    For Each t As String In targetList
        If String.compare(originalList(i), t, true) = 0 Then
            isMatch = true
            Exit For
        End If
    Next

    If isMatch Then
        originalList.RemoveAt(i)
        i -= 1
    End If
Next

但是我的VB.NET代码出现了索引超出范围的错误。我在哪里弄错了?

8 个答案:

答案 0 :(得分:21)

考虑到这一点 - 这是一种更优雅的方式来实现您正在尝试执行的操作 - 即从目标列表中显示的原始列表中删除项目。请考虑以下列表:

Dim OriginalList As New List(Of String)(New String() {"a", "b", "c", "d"})
Dim TargetList As New List(Of String)(New String() {"a", "b", "c"})

以下是我如何删除目标中出现的原始内容...

OriginalList.RemoveAll(Function(OriginalItem) TargetList.Contains(OriginalItem))

将在C#中编写:

OriginalList.RemoveAll(OriginalItem => TargetList.Contains(OriginalItem));

用于完成任务的代码越少,编码错误的可能性就越小。

侧注: 这与测试子集的算法非常相似。如果你想知道集合A是否是B的一个子集,那么你可以迭代B从A中删除任何相应的项目。一旦你完成了对B的迭代,如果A中还有任何项目,那么它就不是B的子集。如果没有剩下的项目,则它是B的子集。

答案 1 :(得分:14)

问题是如何评估结束条件。在C#中,每次循环时,都会检查originalList.Count。在VB.NET版本中,循环的结束步骤在进入循环时计算一次。

来自MSDN:迭代次数。 Visual Basic仅在循环开始之前评估迭代值start,end和step一次。如果语句块更改结束或步骤,则这些更改不会影响循环的迭代。

也就是说,所采用的方法并不高效,因为它可能是使用数组支持的列表,这将涉及大量数据移动。如果元素与目标列表不匹配(如果它们不执行任何操作),则简单地将元素复制到新列表可能会更快,然后在完成后设置originalList = newList。

答案 2 :(得分:7)

Dim i as integer = 0
Dim t as String

For I = originalList.Count to 1 Step -1
    for each t in targetList
       if String.compare(originalList(i), t, true) = 0 then 
          originalList.RemoveAt(I)
          exit for
       end if
    next t
Next I

For ....步骤-1是您可能不熟悉的部分,因为它是VB.NET的基本遗产的一部分。

当遍历集合以通过数字索引移除项目时,您希望从最后开始并继续前进。这将删除计数和要删除的项目的任何问题。

如果C#示例看起来像这样

,它会更清晰
for(int i = originalList.Count; i<0; i--)
{
    foreach (string t in targetList)
    {
        if(String.Compare(originalList[i], t, true) == 0)
        {
                originalList.RemoveAt(i);
                break;
        }
    }
}

答案 3 :(得分:2)

我会把它变成一个while循环来使条件更清晰:

dim i as integer = 0
While i < originalList.Count
    dim isMatch as boolean = false
    for each t as string in targetList
        if String.compare(originalList(i), t, true) = 0 then
                isMatch = true
                Exit for
        end if
    next

    if isMatch then
        originalList.RemoveAt(i)
    else
        i += 1
    end if
next

答案 4 :(得分:0)

如果您要从枚举内联中删除项目,请务必向后迭代。

答案 5 :(得分:0)

使用:

Dim i as Integer
For i = 0 To originalList.Count - 1
    Dim isMatch as boolean = false
    For Each t as string In targetList
        If String.compare(originalList(i), t, true) = 0 Then
            isMatch = true
            Exit For
        End If
    Next

    If isMatch Then
        originalList.RemoveAt(i)
        i -= 1
    End If
Next

最多需要originalList.Count而不是originalList.Count-1

答案 6 :(得分:-1)

在我看来,这是一个问题,如何索引你的字符串,而不是你的for循环。使用调试器逐行执行,您将发现问题。我不想让你省力,因为它将来会帮助你。 :)

答案 7 :(得分:-1)

如果我正确地跟踪你的循环,并且原始列表中的第一项是匹配的,那么你将从索引0处的原始列表中删除该字符串,然后将其减少为-1,这不是当你去检查下一个项目时,有效的索引值。

在我看来,您需要检查您的索引计数,如果您低于0,请将其重置为0,以便能够再次从头开始。