We Are GAP Mobilize
Free Assessment Tool

VB to .NET

WARNING #1049

Use of Null/IsNull() detected.

Description

In Visual Basic 6.0, the Null keyword indicated that a field contained no valid data, and the IsNull function was used to test for Null. In addition, Visual Basic 6 supported Null propagation when Null was used in an expression, the result of the expression would also be Null. For a more thorough discussion of data types in Visual Basic please refer to the Data Type documentation.

Recommendations

In Visual Basic .NET, the Null keyword is still a reserved word, but it has no syntactical value, and the IsNull function is no longer supported.

C# also reserves the null keyword, but it is not to be confused with Null in Visual Basic 6. Visual Basic's Null keyword indicated missing or invalid data in data field, which is the purpose of DbNull in the .Net Framework. C#'s version of null is closer to Visual Basic 6's Nothing keyword.

Also, Null propagation is no longer supported in the .NET framework. When upgrading Visual Basic 6 applications avoid null propagation.

During upgrade, Null is converted to DBNull, and IsNull is converted to IsDBNull of which there are several variants: Visual Basic's IsDBNull function, the Convert.IsDBNull method, the DataTableReader.IsDBNull method, and the IDataRecord.IsDBNull method).

The behavior of DBNull is slightly different than that of Null. Null could be used in functions and assignments as a Variant data type, however DBNull is a class and thus cannot be used as a direct replacement for Visual Basic's Null, DBNull.Value however can be passed as a value type in methods or assignments.

Where Null was used with a Variant data type, the Variant is converted to Object during upgrade; in these cases, depending on context, it may be more appropriate to use the Nothing and the IsNothing function for VB.Net. For C# use the null keyword and compare with null with the equality operators (== and !=).

Sample VB6

Private Sub NullPropagation()
   Dim result As Variant
   Dim resultText AsString
   Dim varRight AsVariant
   Dim varLeft AsVariant

   ' Regular use of Left, Mid, Right
   varRight = "Hello world"
   result = Mid(varRight, 7, 5)
   resultText = resultText & "Mid(" & ResultTxt(varRight) & ", 7, 5) = " & ResultTxt(result) & vbCrLf & vbCrLf

   ' Null propagation 
   ' Trimming of numeric values using Left, Mid, Right
   varLeft = 20
   varRight = 10913857
   result = varLeft + Mid(varRight, 2, 5)
   resultText = resultText & ResultTxt(varLeft) & " + Mid(" & ResultTxt(varRight) & ",2 ,5) = " & ResultTxt(result) & vbCrLf
   varRight = Null
   result = varLeft + Mid(varRight, 2, 5)
   resultText = resultText & ResultTxt(varLeft) & " + Mid(" & ResultTxt(varRight) & ", 2, 5) = " & ResultTxt(result) & vbCrLf & vbCrLf

   ' Null propagation with + operator
   varLeft = Null
   varRight = 45298301
   result = varLeft + Left(varRight, 5)
   resultText = resultText & ResultTxt(varLeft) & " + Left(" & ResultTxt(varRight) & ", 5) = " & ResultTxt(result) & vbCrLf
   varLeft = "18205023"
   result = varLeft + Left(varRight, 5)
   resultText = resultText & ResultTxt(varLeft) & " + Left(" & ResultTxt(varRight) & ", 5) = " & ResultTxt(result) & vbCrLf & vbCrLf

   ' Null propagation with & (Concatenation) operator
   result = varLeft & varRight
   resultText = resultText & ResultTxt(varLeft) & " & " & ResultTxt(varRight) & " = " & ResultTxt(result) & vbCrLf
   MsgBox (resultText)
EndSub

Private Function ResultTxt(var AsVariant)
   If IsNull(var) Then
      ResultTxt = "Null"
   Else If TypeName(var) = "Integer"Or TypeName(var) = "Double"Or TypeName(var) = "Long" Then
      ResultTxt = CStr(var)
   Else
       ResultTxt = """" & var & """"
   End If
End Function

Target VB.NET

Private Sub NullPropagation()
   Dim resultText AsString = ""
   Dim varLeft AsString = CStr(20)

   ' Regular use of Left, Mid, Right
   Dim varRight AsString = "Hello world"
   Dim result AsString = varRight.Substring(6, Math.Min(varRight.Length, 5))
   resultText = resultText & "Mid(" & ResultTxt(varRight) & ", 7, 5) = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10) & Strings.Chr(13) & Strings.Chr(10)

   ' Null propagation
   ' Trimming of numeric values using Left, Mid, Right
   varRight = CStr(10913857)
   result = varLeft & varRight.Substring(1, Math.Min(varRight.Length, 5))
   resultText = resultText & ResultTxt(varLeft) & " + Mid(" & ResultTxt(varRight) & ",2 ,5) = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10)
   'UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   varRight = DBNull.Value
   result = varLeft & varRight.Substring(1, Math.Min(varRight.Length, 5))
   resultText = resultText & ResultTxt(varLeft) & " + Mid(" & ResultTxt(varRight) & ", 2, 5) = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10) & Strings.Chr(13) & Strings.Chr(10)

   ' Null propagation with + operator
   'UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   varLeft = DBNull.Value
   result = varLeft & varRight.Substring(0, Math.Min(varRight.Length, 5))
   resultText = resultText & ResultTxt(varLeft) & " + Left(" & ResultTxt(varRight) & ", 5) = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10)
   varLeft = "18205023"
   result = varLeft & varRight.Substring(0, Math.Min(varRight.Length, 5))
   resultText = resultText & ResultTxt(varLeft) & " + Left(" & ResultTxt(varRight) & ", 5) = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10) & Strings.Chr(13) & Strings.Chr(10)

   'Following statement will throw an error Left$ will not take Null
   'result = varLeft + Left$(varRight, 5)

   ' Null propagation with & (Concatenation) operator
   result = varLeft & varRight
   resultText = resultText & ResultTxt(varLeft) & " & " & ResultTxt(varRight) & " = " & ResultTxt(result) & Strings.Chr(13) & Strings.Chr(10)
   MessageBox.Show(resultText, Application.ProductName)
EndSub

PrivateFunction ResultTxt(ByRef varRight AsString) AsString
   'UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   'UPGRADE_WARNING: (1041) TypeName has a new behavior.
   If Convert.IsDBNull(varRight) Then
      Return"Null"
   Else If varRight.GetType().Name = "Integer"Or varRight.GetType().Name = "Double"Or varRight.GetType().Name = "Long"Then
      Return varRight
   Else
      Return"""" & varRight & """"
   End If
End Function

 

Expected C#

Code that uses Null propagation requires considerable work in either the migrated version or the original VB6 code to remove such propagation.

One approach if the affected code is small is to preface it with an If statement checking for DBNull values, as done in the sample code. Another approach if using a typed DataSet is to take advantage of the built-in IsFieldNameNull() methods to determine if a particular field is set to DBNull.Value. Alternatively, one may use the IsNull() method for DataRows to test if a particular field is DBNull.

Another approach is to create a function that wraps this logic. That's the approach taken with the ResultTxt function which handles the output of DBNulls for us (as well as the display of strings with quotes around them).

In this example, the input sample was limited and given C# strong-type nature we're forced to contemplate many more scenarios in code than with Visual Basic.Net's more dynamic typing. In the solution for this sample reduced the input types to System.Int32 to keep code brief.

Additionally, two methods were created VbLeft and VbMid to replicate the behavior of the original VB functions. The reason for doing this is because the String.Substring is much more stringent about the parameters it takes and bound checks them, throwing an exception if any of them are out of bounds. Visual Basic 6 automatically handled these out of range cases.

C#'s behavior is helpful though in highlighting possible problem areas. So another solution might involve dynamically changing the trim size based on the input. In this case C#'s strongly-type system require we pay more attention to the intent of the code and fix it accordingly.

private string VbMid(string value, int start, int length)
{
   length = (length > value.Length) value.Length - (start - 1) : length;
   if(value.Length > start)
   {
      return value.Substring(start - 1, length);
   }
      return string.Empty;
   }

private string VbLeft(object value, int length)
{
   if (value == null || DBNull.Value.Equals(value))
   {
      return string.Empty;
   }
   else
   {
      string temp = value.ToString();
      if (temp.Length > length)
   {
      return temp.Substring(0, length);
   }
   else return temp;
   }
}

private void NullPropagation()
{
   string resultText = String.Empty;

   // Regular use of Left, Mid, Right
   object varRight = "Hello world";
   object result = VbMid(varRight.ToString(), 7, 5);
   resultText = resultText + "Mid(" + ResultTxt(varRight) + ", 7, 5) = " + ResultTxt(result) + "\r\n" + "\r\n";

   // Null propagation
   // Trimming of numeric values using Left, Mid, Right
   object varLeft = 20;
   varRight = 10913857;
   result = (int)varLeft + Convert.ToInt32(VbMid(varRight.ToString(), 2, 5));
   resultText = resultText + ResultTxt(varLeft) + " + Mid(" + ResultTxt(varRight) + ",2 ,5) = " + ResultTxt(result) + "\r\n";
   //UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   varRight = DBNull.Value;
   int intLeft = (varLeft isint) (int)varLeft : 0;
   // Check for DBNull
   object tempRight = (DBNull.Value.Equals(varRight)) 0 : varRight;
   int intRight = (tempRight isint) (int)tempRight : 0;
   result = intLeft + intRight;
   resultText = resultText + ResultTxt(varLeft) + " + Mid(" + ResultTxt(varRight) + ", 2, 5) = " + ResultTxt(result) + "\r\n" + "\r\n";

   // Null propagation with + operator
   //UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   varLeft = DBNull.Value;
   varRight = "45298301";
   result = varLeft + VbLeft(varRight, 5);//.Substring(0, Math.Min(varRight.Length, 5));
   resultText = resultText + ResultTxt(varLeft) + " + Left(" + ResultTxt(varRight) + ", 5) = " + ResultTxt(result) + "\r\n";
   varLeft = "18205023";
   result = varLeft + VbLeft(varRight, 5);//.Substring(0, Math.Min(varRight.Length, 5));
   resultText = resultText + ResultTxt(varLeft) + " + Left(" + ResultTxt(varRight) + ", 5) = " + ResultTxt(result) + "\r\n" + "\r\n";

   // Null propagation with & (Concatenation) operator
   result = varLeft.ToString() + varRight.ToString();
   resultText = resultText + ResultTxt(varLeft) + " & " + ResultTxt(varRight) + " = " + ResultTxt(result) + "\r\n";
   MessageBox.Show(resultText, Application.ProductName);
}

private string ResultTxt(object var)
{
   //UPGRADE_WARNING: (1049) Use of Null/IsNull() detected.
   //UPGRADE_WARNING: (1041) TypeName has a new behavior.
   if (Convert.IsDBNull(var))
   {
      return"Null";
   }
   else if (var is int || var is double || var is long)
   {
      return var.ToString();
   }
   else
   {
      return"\"" + var + "\"";
   }
}
Talk To An Engineer