WARNING #6021

    Casting 'int' to Enum may cause different behavior.

    Description

    Enum's in .Net are integral types and therefore any valid integral value can be cast to an Enum type. This is still possible even when the value being cast is outside of the values defined for the given enumeration!

    Thus, when mixing integers with Enums it is possible to create invalid Enumeration instances that do not reference any of the defined values for that Enumeration.

    Recommendations

    • One possible workaround is to use the Enum.IsDefined() method to verify if a given integral value is defined for a given Enumeration. This method however will not work for enumerations marked with the Flags attribute and which are used as a bit map.
    • Additionally, one can ensure logic checks explicitly for defined Enum values and does not assume Enum-typed variables will conform to the defined list of values.
    • In many cases, functional equivalence will be maintained, but the effort should be made to eliminate these casts to ensure cleaner code.

    Source VB6

    Public Enum HealthState
         Alive
         Dead
         Unknown
    End Enum
    
    Public Sub Kill(ByRef health As HealthState, Optional ByVal command As Integer = 1)
         health = command
    End Sub
    

    Target VB.NET

    Public Enum HealthState
    	Alive
    	Dead
    	Unknown
    End Enum
    
    Public Sub Kill(ByRef health As HealthState, Optional ByVal command As Integer = 1)
    	health = command
    End Sub
    

    Target C#

    public enum HealthState
    {
    	Alive,
    	Dead,
    	Unknown
    }
    
    internal static void Kill(ref HealthState health, int command = 1)
    {
    	//UPGRADE_WARNING: (6021) Casting 'int' to Enum may cause different behaviour.
    	health = (HealthState)command;
    }
    

     

    To better illustrate this issue, here's an example from C#:

    public enum MyBoolean
    {
       True = -1,
       False = 0,
       FileNotFound = 1
    }
    

    In this case there are three defined values for MyBoolean: True (-1), False (0) and FileNotFound (-1). It is often times assumed that a variable of type MyBoolean will only hold one of these three values. This is incorrect!

    The following statement is valid C#, and it does not throw any kind of Exception during run time.

    MyBoolean b = (MyBoolean)45;
    

     

    In this case, b will have a value of 45 and will not be a defined value for MyBoolean. However, in cases where code has not followed best practices this can lead to errors that hurt functional equivalence.

    For example:

    public static void DeleteFile(MyBoolean delete)
    {
    if (delete == MyBoolean.False) return;
    if (delete == MyBoolean.FileNotFound)
    {
       throw new InvalidOperationException("File does not exist.");
    }
    File.Delete("important.log");
    }
    

     

    In this case, the developer assumed that only if delete was MyBoolean.True would the code reach the File.Delete statement. Such constructions can be common.

    Enum.IsDefined method could have been used to verify if a given integral value is defined for a given Enumeration. This method however will not work for enumerations marked with the Flags attribute and which are used as a bit map.

    Additionally, one can ensure logic checks explicitly for defined Enum values and does not assume Enum-typed variables will conform to the defined list of values.

    Finally, in many cases functional equivalence will be maintained, but effort should be made to eliminate these casts to ensure cleaner code.

     


    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