.net - 由于增量运算符或自动字符串转换(我认为)无法将代码从c#转换为vb.net

时间:2009-04-09 21:20:11

标签: c# .net vb.net

我正在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-method”) - 或者由于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.

我应该说课程中的代码对我来说非常先进(我是一个爱好程序员但每天都在学习)所以也许我看不到明显的事情,但这就是我问你的原因。< / p> 你可以给我任何提示来解决这个问题吗?

谢谢。

编辑: 这是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 个答案:

答案 0 :(得分:3)

while循环的第二行的参数在VB.NET版本中是完全不同的。 Interlocked.Increment调用将返回递增的索引,而C#post-increment运算符返回原始值(在增量之前)。

第二行可能会更好地替换为:

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

即。只有在完成索引/赋值后才按照C#原始值递增值。

答案 1 :(得分:2)

我可能会遗漏一些东西,但我没有看到转换器为何开始使用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

答案 2 :(得分:1)

索引越界意味着您尝试访问数组大小之外的内容。这通常是由“一个接一个”的问题引起的。

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

你说的是一个自动化工具吗?

顺便说一句,您可以毫不费力地在VB应用程序中包含C#类和程序集,那么为什么要转换它呢?

答案 3 :(得分:0)

将Math.Max更改为Math.Min应该可以解决问题,但是为了清楚起见,我会像itowlson所说的那样改变,并在使用后将增量移动到。

答案 4 :(得分:0)

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_primaryKeyLength和m_primaryKey.Length是多余的。如果是这种情况,请将“m_primaryKeyLength”替换为“m_primaryKey.Length”来简化代码。