Reputation: 131
I have a VB.net project that I have converted over to C#. One part of the code gives a different result in C# than it does in VB.Net. Can someone tell me what is wrong with the C# code here and how to fix it?
VB.Net:
Private Sub mco_GetDataReturn(ByVal TransactionNumber As Short, ByVal DataType As ModiconComunications.ModiconComObject.GetDataType, ByVal Success As Boolean, ByVal UserData() As Byte) Handles mco.GetDataReturn
OrderNumber = ""
HeatNumber = ""
If UserData.GetUpperBound(0) < 17 Then
'MsgBox("ModComm1_GetDataReturn - Not enough data returned from PLC read : " & UBound(UserData, 1) + 1 & " bytes")
ReDim Preserve UserData(0 To 17)
ElseIf UserData.GetUpperBound(0) > 17 Then
'MsgBox("ModComm1_GetDataReturn - Too much data returned from PLC read : " & UBound(UserData, 1) + 1 & " bytes")
ReDim Preserve UserData(0 To 17)
End If
OrderNumber = System.Text.Encoding.ASCII.GetChars(UserData, 0, 8)
OrderRelease = System.Text.Encoding.ASCII.GetChars(UserData, 8, 2)
HeatNumber = System.Text.Encoding.ASCII.GetChars(UserData, 10, 6)
PieceNumber = UserData(16) * 256 + UserData(17)
End Sub
C#:
private void mco_GetDataReturn(short TransactionNumber, ModiconComunications.ModiconComObject.GetDataType DataType, bool Success, byte[] UserData)
{
OrderNumber = "";
HeatNumber = "";
if (UserData.GetUpperBound(0) < 17)
{
Array.Resize(ref UserData, 18);
}
else if (UserData.GetUpperBound(0) > 17)
{
Array.Resize(ref UserData, 18);
}
OrderNumber = System.Text.Encoding.ASCII.GetString(UserData, 0, 8).ToString();
OrderRelease = System.Text.Encoding.ASCII.GetString(UserData, 8, 2).ToString();
HeatNumber = System.Text.Encoding.ASCII.GetString(UserData, 10, 6).ToString();
PieceNumber = UserData[16] * 256 + UserData[17];
}
The specific problem is with the last statement for PieceNumber. In VB.Net the statement produces the actual piece number, however in the C# code it produces 0 (zero). How do these statements differ? The PieceNumber variable is declared as an int in both projects.
Upvotes: 1
Views: 732
Reputation: 3685
following code (in LinQPad) works as expected. Give us some sample data to investigate.
var testData = new Dictionary<string, int> {
{ "01234567890123", 0 },
{ "012345678901234", 0 },
{ "0123456789012345", 0 },
{ "01234567890123456", 13824 },
{ "012345678901234567", 13879 },
{ "0123456789012345678", 13879 },
{ "01234567890123456789", 13879 },
{ "012345678901234567890", 13879 }
};
foreach (var pair in testData){
var testCase = pair.Key;
var expected = pair.Value;
var UserData = System.Text.Encoding.ASCII.GetBytes(testCase);
if (UserData.GetUpperBound(0) < 17)
{
Array.Resize(ref UserData, 18);
}
else if (UserData.GetUpperBound(0) > 17)
{
Array.Resize(ref UserData, 18);
}
var OrderNumber = System.Text.Encoding.ASCII.GetString(UserData, 0, 8).ToString();
var OrderRelease = System.Text.Encoding.ASCII.GetString(UserData, 8, 2).ToString();
var HeatNumber = System.Text.Encoding.ASCII.GetString(UserData, 10, 6).ToString();
var PieceNumber = UserData[16] * 256 + UserData[17];
(new {
TestCase = testCase,
OrderNumber,
OrderRelease,
HeatNumber,
PieceNumber,
Success = PieceNumber == expected
}).Dump();
}
Upvotes: 0
Reputation: 12913
In VB.net, when you create an array with new Array(10), you indicate that its upper bound will be 10, thus it contains 11 elements.
In C#, new Array(10) will create an array of 10 elements (from 0 to 9). I guess it's the root of your problem.
Upvotes: 2
Reputation: 14591
Doesn't it depend on the initial content of UserData
? Are you sure you call it with the same parameters?
if it is, say, 10 bytes long, and you resize it to 18 bytes, the 'new' values will be zero.
Thus UserData[16] * 256 + UserData[17]
== 0 * 256 + 0
= 0
Besides, in VB you have
OrderNumber = System.Text.Encoding.ASCII.GetChars(UserData, 0, 8)
While in C# you have
OrderNumber = System.Text.Encoding.ASCII.GetString(UserData, 0, 8).ToString();
You do that also for other two strings? Why the difference if it is a simple rewrite?
Upvotes: 0