- INDEX VB TO NET
- KNOWLEDGE BASE
- EWI-TODO
- TODO #1059
TODO #1059
Code was upgraded to use 1% which may not have the same behavior.
Description
This EWI appears when a Visual Basic method call is changed to a .NET counterpart that may not have the same behavior as the original.
Recommendations
In most cases the .NET equivalents provide equivalent functionality but there can be edge cases for which its functionality differs. Most commonly VB6 performed a lot of validations and auto coercions.
Unfortunately, there is such a wide variety of cases that might cause this EWI that it would be prohibitive to list them all with possible resolutions.
It is however important to note that often times these differences can depend on the parameters passed to the methods. Thus choosing a different signature of the same method might provide the desired functionality.
Therefore, it is recommended that the migration consultant research the target and source methods to achieve the desired functionality.
Sample VB6
For example this problem can happen while migrating assignments of strings to byte arrays. Byte arrays are somewhat special because VB6 lets you directly assign strings to them.
In this case, VB6 performs a direct memory copy of the contents of the string. Because all VB5 and VB6 strings are Unicode strings (two bytes per character), the target array is re-dimensioned to account for the actual string length in bytes. Most of the code meets functional equivalence. In some cases Mobilize.NET own migration library is used as it more closely matches Visual Basic 6 in behavior, however for this particular case the System.Text.Encoding.Unicode.GetString and System.Text.Encoding.Unicode.GetBytes methods provide very similar functionality. The Mobilize library method StringsHelper.ByteArrayToString provides checking for edge cases where an odd number of bytes are sent thus resulting in an invalid Unicode sequence.
Public Function CoercionArrayToString(ByRef ByteArray() As Byte) As String
CoercionArrayToString = ByteArray
End Function
Public Function CoercionStringToArray(ByVal ByteText As String) As Byte()
CoercionStringToArray = ByteText
End Function
Target VB.NET
Public Function CoercionArrayToString(ByRef ByteArray() AsByte) As String
'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
Return StringsHelper.ByteArrayToString(ByteArray)
End Function
Public Function CoercionStringToArray(ByVal ByteText AsString) AsByte()
'UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.
Return UnicodeEncoding.Unicode.GetBytes(ByteText)
End Function
Private Sub Command1_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles Command1.Click
' Strings in VB6 are Unicode and take 2 bytes per character
' Build a byte array of byte pairs to create the alphabet
' and a series of double byte values (unicode)
Dim myAlphabet(26 * 4 - 1) As Byte
For i AsInteger = 0 To (26 * 4 - 1)
If i Mod 2 = 0 Then
myAlphabet(i) = 65 + (i / 2)
Else
If i < (26 * 2) Then
myAlphabet(i) = 0
Else
myAlphabet(i) = 1
End If
End If
Next
' myAlphabet now holds these values:
' "65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0"
Dim text_Renamed AsString = LiteralArray(myAlphabet)
' Write byte values to text file, there one can better appreciate unicode chars
WriteFile("C:\alpha.txt", myAlphabet)
' Coerce ByteArray to String through function
Dim coercedString AsString = CoercionArrayToString(myAlphabet)
' Coerce string to array and write results to file to verify no data has been lost
WriteFile("C:\beta.txt", CoercionStringToArray(coercedString))
' text holds literal byte representation
MessageBox.Show(text_Renamed, Application.ProductName)
MessageBox.Show(coercedString, Application.ProductName)
Dim coercedBytes() AsByte = CoercionStringToArray("1 2 3 4 5 6 7")
'UPGRADE_WARNING: (1041) LenB has a new behavior.
text_Renamed = "1 2 3 4 5 6 7 Length: " & ("1 2 3 4 5 6 7").Length & " LenB: " & CStr(Encoding.Unicode.GetByteCount("1 2 3 4 5 6 7")) & Strings.Chr(13) & Strings.Chr(10)
text_Renamed = text_Renamed & LiteralArray(coercedBytes)
MessageBox.Show(text_Renamed, Application.ProductName)
'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName)
End Sub
Private Function LiteralArray(ByRef bytes() As Byte) As String
Dim text_Renamed As String = ""
For Each bytes_item As Byte In bytes
text_Renamed = text_Renamed & CStr(bytes_item) & " "
Next bytes_item
Return text_Renamed
End Function
Private Sub WriteFile(ByRef fileName As String, ByRef bytes() As Byte)
Try
File.Delete(fileName)
Catch
End Try
Dim fnum AsInteger
' Save the file.
fnum = FileSystem.FreeFile()
FileSystem.FileOpen(fnum, fileName, OpenMode.Binary)
'UPGRADE_WARNING: (1041) Put was upgraded to FilePutObject and has a new behavior.
FileSystem.FilePutObject(fnum, bytes, 1)
FileSystem.FileClose(fnum)
End Sub
Expected VB.NET
In this case most of the code meets functional equivalence. In some cases Mobilize own migration library is used as it more closely matches VB6 in behavior, however for this particular case the System.Text.Encoding.Unicode.GetString and System.Text.Encoding.Unicode.GetBytes methods provide very similar functionality. The Mobilize library provides checking for edge cases where an odd number of bytes are sent thus resulting in an invalid Unicode sequence.
The only correction that had to be done was to fix the auxiliary WriteFile method.
Public Function CoercionArrayToString(ByRef ByteArray() As Byte) As String
'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
Return StringsHelper.ByteArrayToString(ByteArray)
End Function
Public Function CoercionStringToArray(ByVal ByteText As String) As Byte()
'UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.
Return UnicodeEncoding.Unicode.GetBytes(ByteText)
End Function
Private Sub Command1_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles Command1.Click
' Strings in VB6 are Unicode and take 2 bytes per character
' Build a byte array of byte pairs to create the alphabet
' and a series of double byte values (unicode)
Dim myAlphabet(26 * 4 - 1) AsByte
For i AsInteger = 0 To (26 * 4 - 1)
If i Mod 2 = 0 Then
myAlphabet(i) = 65 + (i / 2)
Else
If i < (26 * 2) Then
myAlphabet(i) = 0
Else
myAlphabet(i) = 1
End If
End If
Next
' myAlphabet now holds these values:
' "65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0"
Dim text_Renamed AsString = LiteralArray(myAlphabet)
' Write byte values to text file, there one can better appreciate unicode chars
WriteFile("C:\alpha.txt", myAlphabet)
' Coerce ByteArray to String through function
Dim coercedString AsString = CoercionArrayToString(myAlphabet)
' Coerce string to array and write results to file to verify no data has been lost
WriteFile("C:\beta.txt", CoercionStringToArray(coercedString))
' text holds literal byte representation
MessageBox.Show(text_Renamed, Application.ProductName)
MessageBox.Show(coercedString, Application.ProductName)
Dim coercedBytes() AsByte = CoercionStringToArray("1 2 3 4 5 6 7")
'UPGRADE_WARNING: (1041) LenB has a new behavior.
text_Renamed = "1 2 3 4 5 6 7 Length: " & ("1 2 3 4 5 6 7").Length & " LenB: " & CStr(Encoding.Unicode.GetByteCount("1 2 3 4 5 6 7")) & Strings.Chr(13) & Strings.Chr(10)
text_Renamed = text_Renamed & LiteralArray(coercedBytes)
MessageBox.Show(text_Renamed, Application.ProductName)
'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName)
EndSub
Private Function LiteralArray(ByRef bytes() As Byte) As String
Dim text_Renamed As String = ""
For Each bytes_item As Byte In bytes
text_Renamed = text_Renamed & CStr(bytes_item) & " "
Next bytes_item
Return text_Renamed
End Function
Private Sub WriteFile(ByRef fileName As String, ByRef bytes() As Byte)
Try
File.Delete(fileName)
Catch
EndTry
File.WriteAllBytes(fileName, bytes)
End Sub
Target C#
public string CoercionArrayToString(byte[] ByteArray)
{
//UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
return StringsHelper.ByteArrayToString(ByteArray);
}
public byte[] CoercionStringToArray(string ByteText)
{
//UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.
return UnicodeEncoding.Unicode.GetBytes(ByteText);
}
private void Command1_Click(Object eventSender, EventArgs eventArgs)
{
// Strings in VB6 are Unicode and take 2 bytes per character
// Build a byte array of byte pairs to create the alphabet
// and a series of double byte values (unicode)
byte[] myAlphabet = new byte[26 * 4];
for (int i = 0; i <= (26 * 4 - 1); i++)
{
if (i % 2 == 0)
{
myAlphabet[i] = Convert.ToByte(65 + (i / 2d));
}
else
{
if (i < (26 * 2))
{
myAlphabet[i] = 0;
}
else
{
myAlphabet[i] = 1;
}
}
}
// myAlphabet now holds these values:
// "65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0"
string text_Renamed = LiteralArray(myAlphabet);
// Write byte values to text file, there one can better appreciate unicode chars
WriteFile("C:\\alpha.txt", myAlphabet);
// Coerce ByteArray to String through function
string coercedString = CoercionArrayToString(myAlphabet);
// Coerce string to array and write results to file to verify no data has been lost
WriteFile("C:\\beta.txt", CoercionStringToArray(coercedString));
// text holds literal byte representation
MessageBox.Show(text_Renamed, Application.ProductName);
MessageBox.Show(coercedString, Application.ProductName);
byte[] coercedBytes = (byte[])CoercionStringToArray("1 2 3 4 5 6 7");
//UPGRADE_WARNING: (1041) LenB has a new behavior.
text_Renamed = "\"1 2 3 4 5 6 7\" Length: " + ("1 2 3 4 5 6 7").Length.ToString() + " LenB: " + Encoding.Unicode.GetByteCount("1 2 3 4 5 6 7").ToString() + "\r\n";
text_Renamed = text_Renamed + LiteralArray(coercedBytes);
MessageBox.Show(text_Renamed, Application.ProductName);
//UPGRADE_TODO: (1059) Code was upgraded to use UpgradeHelpers.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName);
}
private string LiteralArray(byte[] bytes)
{
string text_Renamed = "";
foreach (byte bytes_item in bytes)
{
text_Renamed = text_Renamed + bytes_item.ToString() + " ";
}
return text_Renamed;
}
private void WriteFile(string fileName, byte[] bytes)
{
try
{
File.Delete(fileName);
}
catch
{}
int fnum = 0;
// Save the file.
fnum = FileSystem.FreeFile();
FileSystem.FileOpen(fnum, fileName, OpenMode.Binary, OpenAccess.Default, OpenShare.Default, -1);
//UPGRADE_WARNING: (1041) Put was upgraded to FilePutObject and has a new behavior.
FileSystem.FilePutObject(fnum, bytes, Convert.ToInt32(1));
FileSystem.FileClose(fnum);
}
Expected C#
In this case most of the code meets functional equivalence. In some cases Artinsoft's own migration library is used as it more closely matches Visual Basic 6 in behavior, however for this particular case the System.Text.Encoding.Unicode.GetString and System.Text.Encoding.Unicode.GetBytes methods provide very similar functionality. The Mobilize library provides checking for edge cases where an odd number of bytes are sent thus resulting in an invalid Unicode sequence.
The only correction that had to be done was to fix the auxiliary WriteFile method.
public string CoercionArrayToString(byte[] ByteArray)
{
//UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
return StringsHelper.ByteArrayToString(ByteArray);
}
public byte[] CoercionStringToArray(string ByteText)
{
//UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.
return UnicodeEncoding.Unicode.GetBytes(ByteText);
}
private void Command1_Click(Object eventSender, EventArgs eventArgs)
{
// Strings in VB6 are Unicode and take 2 bytes per character
// Build a byte array of byte pairs to create the alphabet
// and a series of double byte values (unicode)
byte[] myAlphabet = new byte[26 * 4];
for (int i = 0; i <= (26 * 4 - 1); i++)
{
if (i % 2 == 0)
{
myAlphabet[i] = Convert.ToByte(65 + (i / 2d));
}
else
{
if (i < (26 * 2))
{
myAlphabet[i] = 0;
}
else
{
myAlphabet[i] = 1;
}
}
}
// myAlphabet now holds these values:
// "65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0"
string text_Renamed = LiteralArray(myAlphabet);
// Write byte values to text file, there one can better appreciate unicode chars
WriteFile("C:\\alpha.txt", myAlphabet);
// Coerce ByteArray to String through function
string coercedString = CoercionArrayToString(myAlphabet);
// Coerce string to array and write results to file to verify no data has been lost
WriteFile("C:\\beta.txt", CoercionStringToArray(coercedString));
// text holds literal byte representation
MessageBox.Show(text_Renamed, Application.ProductName);
MessageBox.Show(coercedString, Application.ProductName);
byte[] coercedBytes = (byte[])CoercionStringToArray("1 2 3 4 5 6 7");
//UPGRADE_WARNING: (1041) LenB has a new behavior.
text_Renamed = "\"1 2 3 4 5 6 7\" Length: " + ("1 2 3 4 5 6 7").Length.ToString() + " LenB: " + Encoding.Unicode.GetByteCount("1 2 3 4 5 6 7").ToString() + "\r\n";
text_Renamed = text_Renamed + LiteralArray(coercedBytes);
MessageBox.Show(text_Renamed, Application.ProductName);
//UPGRADE_TODO: (1059) Code was upgraded to use UpgradeHelpers.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.
MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName);
}
private string LiteralArray(byte[] bytes)
{
string text_Renamed = "";
foreach (byte bytes_item in bytes)
{
text_Renamed = text_Renamed + bytes_item.ToString() + " ";
}
return text_Renamed;
}
private void WriteFile(string fileName, byte[] bytes)
{
try
{
File.Delete(fileName);
}
catch
{
}
File.WriteAllBytes(fileName, bytes);
}