代码之家  ›  专栏  ›  技术社区  ›  moster67

.NET-由于增量运算符或自动字符串转换,无法将代码从C转换为VB.NET(我认为)

  •  0
  • moster67  · 技术社区  · 17 年前

    我正在用vb.net编写一个库,在这个库中,我添加了一个最初用c语言编写但转换为vb.net的类。我对C不太了解,所以我使用了在线C到VB.NET转换器。现在我陷入了一些代码的困境,我相信在线转换器不能正确地“翻译”。

    运行代码时,我得到以下错误:

    System.IndexOutOfRangeException was unhandled
      Message="IndexOutOfRangeException"
      StackTrace:
        at System.String.get_Chars()
    .........
    

    我真的不明白这个错误的原因。我认为这个错误可能是由于以下两个原因之一: -C能够自动将整型变量转换为字符串(而VB.NET需要“ToString方法”)。 -或者由于C正在使用VB.NET不支持的增量运算符。

    这里是C中的原始代码段,其中“m_primarykey”是一个StringBuilder对象:

    private void addMetaphoneCharacter(String primaryCharacter, String alternateCharacter)
            {
                //Is the primary character valid?
                if (primaryCharacter.Length > 0)
                {
                    int idx = 0;
                    while (idx < primaryCharacter.Length)
                    {
                        m_primaryKey.Length++;
                        m_primaryKey[m_primaryKeyLength++] = primaryCharacter[idx++];
                    }
                }
                //other code deleted
    

    当使用在C中创建的类库时,此原始代码可以工作。

    下面是在vb.net中转换的代码,它给出了前面提到的错误:

    Private Sub addMetaphoneCharacter(ByVal primaryCharacter As String, ByVal alternateCharacter As String)
                'Is the primary character valid? 
                If primaryCharacter.Length > 0 Then
                    Dim idx As Integer = 0
                    While idx < primaryCharacter.Length
                        m_primaryKey.Length += 1
                        m_primaryKey(System.Math.Max(System.Threading.Interlocked.Increment(m_primaryKeyLength), _
                            m_primaryKeyLength - 1)) = primaryCharacter _
                            (System.Math.Max(System.Threading.Interlocked.Increment(idx), idx - 1))
                    End While
                End If 
               'other code deleted  
    

    可以找到原始代码 here.

    我应该说,课堂上的代码对我来说相当先进(我是一个业余程序员,但每天都在学习),所以也许我看不到明显的东西,但这就是我问你的原因。

    你能给我一些提示来解决这个问题吗?

    谢谢您。

    编辑: 这是C中的完整子组件:

    /**
             * Appends a metaphone character to the primary, and a possibly different alternate,
             * metaphone keys for the word.
             * 
             * @param primaryCharacter
             *               Primary character to append to primary key, and, if no alternate char is present,
             *               the alternate key as well
             * @param alternateCharacter
             *               Alternate character to append to alternate key.  May be null or a zero-length string,
             *               in which case the primary character will be appended to the alternate key instead
             */
            private void addMetaphoneCharacter(String primaryCharacter, String alternateCharacter)
            {
                //Is the primary character valid?
                if (primaryCharacter.Length > 0)
                {
                    int idx = 0;
                    while (idx < primaryCharacter.Length)
                    {
                        m_primaryKey.Length++;
                        m_primaryKey[m_primaryKeyLength++] = primaryCharacter[idx++];
                    }
                }
    
                //Is the alternate character valid?
                if (alternateCharacter != null)
                {
                    //Alternate character was provided.  If it is not zero-length, append it, else
                    //append the primary string as long as it wasn't zero length and isn't a space character
                    if (alternateCharacter.Length > 0)
                    {
                        m_hasAlternate = true;
                        if (alternateCharacter[0] != ' ')
                        {
                            int idx = 0;
                            while (idx < alternateCharacter.Length)
                            {
                                m_alternateKey.Length++;
                                m_alternateKey[m_alternateKeyLength++] = alternateCharacter[idx++];
                            }
                        }
                    }
                    else
                    {
                        //No, but if the primary character is valid, add that instead
                        if (primaryCharacter.Length > 0 && (primaryCharacter[0] != ' '))
                        {
                            int idx = 0;
                            while (idx < primaryCharacter.Length)
                            {
                                m_alternateKey.Length++;
                                m_alternateKey[m_alternateKeyLength++] = primaryCharacter[idx++];
                            }
                        }
                    }
                }
                else if (primaryCharacter.Length > 0)
                {
                    //Else, no alternate character was passed, but a primary was, so append the primary character to the alternate key
                    int idx = 0;
                    while (idx < primaryCharacter.Length)
                    {
                        m_alternateKey.Length++;
                        m_alternateKey[m_alternateKeyLength++] = primaryCharacter[idx++];
                    }
                }
            }
    
    5 回复  |  直到 17 年前
        1
  •  3
  •   itowlson    17 年前

    在vb.net版本中,while循环第二行的参数非常不同。interlocked.increment调用将返回递增的索引,而c post increment运算符返回原始值(在递增之前)。

    第二行可能会更好地替换为以下内容:

    m_primaryKey(m_primaryKeyLength) = primaryCharacter(idx)
    m_primaryKeyLength = m_primaryKeyLength + 1
    idx = idx + 1
    

    也就是说,只有在完成索引/分配之后,才能按照C原始值递增值。

        2
  •  2
  •   Martin Clarke    17 年前

    我可能遗漏了一些东西,但是我看不出转换器为什么开始使用System.Threading.Interlocked….

    我的手动转换如下所示:

    Private Sub addMetaphoneCharacter(ByVal primaryCharacter As String, ByVal alternateCharacter As String)
                'Is the primary character valid? 
                If primaryCharacter.Length > 0 Then
                    Dim idx As Integer = 0
                    While idx < primaryCharacter.Length
                        m_primaryKey.Length += 1
                        m_primaryKey(m_primaryKeyLength) = primaryCharacter(idx)
                        m_primaryKeyLength += 1
                        idx += 1
    
                    End While
                End If 
               'other code deleted
    
        3
  •  1
  •   FlySwat    17 年前

    索引超出界限意味着您正试图访问数组大小之外的内容。这通常是由“一劳永逸”问题引起的。

    看看代码,vb转换是相当奇怪的,并且正在做一些C版本没有做的事情,例如从索引器中删除一个。

    你是说自动化工具做到了吗?

    顺便说一下,您可以在VB应用程序中包含C类和程序集,而不会有任何问题,那么为什么要转换它呢?

        4
  •  0
  •   JoshL    17 年前

    while循环中的两行代码在C中执行以下操作: -将m\primarykey.length增加1 -将m“primarykeylength”增加一个(您确定这里没有漏掉一个点吗?) -IDX增加1 -将primarycharacter[idx]的值赋给m_primarykey[m_primarykeylength]

    所以在VB代码中…

    m_primaryKey.Length += 1
    m_primaryKeyLength += 1
    idx += 1
    
    m_primaryKey(m_primaryKeyLength) = primaryCharacter (idx)
    

    我不能从这个代码片段中分辨出来,但它闻起来像m洇primarykey length和m洇primarykey.length是多余的。如果是这种情况,请通过将“m_primarykey length”替换为“m_primarykey.length”来简化代码。

        5
  •  0
  •   Neil N HLGEM    16 年前

    把math.max改成math.min应该可以解决这个问题,但是为了清晰起见,我会像伊托森所说的那样改变,并在使用完之后将增量改为。