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);
    }


    Download VBUC Free Trial
    Download VBUC Now

    It's time to eradicate VB6
    ROI of eradicating VB6

    8 Proven Tips for
    Planning a Successful Migration

    8 Tips for migration