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

Jac*_*ack 3 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--;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*ter 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"})
Run Code Online (Sandbox Code Playgroud)

这是我如何删除目标中出现的原始项目...

OriginalList.RemoveAll(Function(OriginalItem) TargetList.Contains(OriginalItem))
Run Code Online (Sandbox Code Playgroud)

在C#中写的是:

OriginalList.RemoveAll(OriginalItem => TargetList.Contains(OriginalItem));
Run Code Online (Sandbox Code Playgroud)

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

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


Yul*_*liy 14

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

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

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


RS *_*ley 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
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)