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

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 recommeded that the migration consultant research the target and source methods to achieve the desired functionality.

In this particular code sample we'll be presenting a case of implicit data type coercion.

Sample VB6

PublicFunction CoercionArrayToString(ByRef ByteArray() AsByte) AsString

CoercionArrayToString = ByteArray

EndFunction

PublicFunction CoercionStringToArray(ByVal ByteText AsString) AsByte()

CoercionStringToArray = ByteText

EndFunction

Target VB.NET

PublicFunction CoercionArrayToString(ByRef ByteArray() AsByte) AsString

'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

Return StringsHelper.ByteArrayToString(ByteArray)

EndFunction

PublicFunction 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)

EndFunction

PrivateSub Command1_Click(ByVal eventSender AsObject, 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

EndIf

EndIf

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

PrivateFunction LiteralArray(ByRef bytes() AsByte) AsString

Dim text_Renamed AsString = ""

ForEach bytes_item AsByteIn bytes

text_Renamed = text_Renamed & CStr(bytes_item) & " "

Next bytes_item

Return text_Renamed

EndFunction

PrivateSub WriteFile(ByRef fileName AsString, ByRef bytes() AsByte)

Try

File.Delete(fileName)

Catch

EndTry

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)

EndSub

Expected VB.NET

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 Artinsoft 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.

PublicFunction CoercionArrayToString(ByRef ByteArray() AsByte) AsString

'UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

Return StringsHelper.ByteArrayToString(ByteArray)

EndFunction

PublicFunction 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)

EndFunction

PrivateSub Command1_Click(ByVal eventSender AsObject, 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

EndIf

EndIf

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

PrivateFunction LiteralArray(ByRef bytes() AsByte) AsString

Dim text_Renamed AsString = ""

ForEach bytes_item AsByteIn bytes

text_Renamed = text_Renamed & CStr(bytes_item) & " "

Next bytes_item

Return text_Renamed

EndFunction

PrivateSub WriteFile(ByRef fileName AsString, ByRef bytes() AsByte)

Try

File.Delete(fileName)

Catch

EndTry

File.WriteAllBytes(fileName, bytes)

EndSub

Target C#

publicstring CoercionArrayToString(byte[] ByteArray)

{

//UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

returnStringsHelper.ByteArrayToString(ByteArray);

}

publicbyte[] CoercionStringToArray(string ByteText)

{

//UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.

returnUnicodeEncoding.Unicode.GetBytes(ByteText);

}

privatevoid 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 = newbyte[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 Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName);

}

privatestring LiteralArray(byte[] bytes)

{

string text_Renamed = "";

foreach (byte bytes_item in bytes)

{

text_Renamed = text_Renamed + bytes_item.ToString() + " ";

}

return text_Renamed;

}

privatevoid 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 Artinsoft 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.

publicstring CoercionArrayToString(byte[] ByteArray)

{

//UPGRADE_TODO: (1059) Code was upgraded to use Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

returnStringsHelper.ByteArrayToString(ByteArray);

}

publicbyte[] CoercionStringToArray(string ByteText)

{

//UPGRADE_TODO: (1059) Code was upgraded to use System.Text.UnicodeEncoding.Unicode.GetBytes() which may not have the same behavior.

returnUnicodeEncoding.Unicode.GetBytes(ByteText);

}

privatevoid 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 = newbyte[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 Artinsoft.VB6.Utils.StringsHelper.ByteArrayToString() which may not have the same behavior.

MessageBox.Show(StringsHelper.ByteArrayToString(coercedBytes), Application.ProductName);

}

privatestring LiteralArray(byte[] bytes)

{

string text_Renamed = "";

foreach (byte bytes_item in bytes)

{

text_Renamed = text_Renamed + bytes_item.ToString() + " ";

}

return text_Renamed;

}

privatevoid WriteFile(string fileName, byte[] bytes)

{

try

{

File.Delete(fileName);

}

catch

{

}

File.WriteAllBytes(fileName, bytes);

}

Updated for VBUC v3.0

Last generated on 6/19/2009 9:46:38 AM