我正在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++];
}
}
}
答案 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”来简化代码。