Directcast & Ctype differences with enums

 Public Enum Fruit
    Red_Apple = 1
End Enum
Private Sub InitCombosRegular()
    Dim d1 As New Dictionary(Of Int16, String)
    For Each e In [Enum].GetValues(GetType(Fruit))
        d1.Add(CShort(e), Replace(e.ToString, "_", " "))
    ComboBox1.DataSource = d1.ToList
    ComboBox1.DisplayMember = "Value"
    ComboBox1.ValueMember = "Key"
    ComboBox1.SelectedIndex = 0
End Sub

   'This fails
        Dim combo1 = DirectCast(ComboBox1.SelectedValue, Fruit) ' Fails
        'these both work
        Dim combo2 = DirectCast(CInt(ComboBox1.SelectedValue), Fruit) 'works
        Dim combo3 = CType(ComboBox1.SelectedValue, Fruit) 'works

Why does the CType work and the DirectCast does not with the same syntax? Yet if I cast the selectedValue to an int before I DirectCast, then it works



13.10.2009 18:49:06

The reason why is because CType and DirectCast are fundamentally different operations.

DirectCast is a casting mechanism in VB.Net which allows for only CLR defined conversions. It is even more restrictive than the C# version of casting because it doesn't consider user defined conversions.

CType is a lexical casting mechanism. It considers CLR rules, user defined conversions and VB.Net defined conversions. In short it will do anything and everything possible to create a valid conversion for an object to a specified type.

In this particular case you are trying to convert a value to an Enum which does not have a CLR defined conversion and hence it's failing. The VB.Net runtime however was able to find a lexical conversion to satisfy the problem.

A decent discussion on the differences exists here:

9.02.2015 20:13:11
Thanks. What would be the best practice on this? Explicit cast the selectedValue to an int and directcast(#2), or just Ctype(#3)
Eric 13.10.2009 19:52:16
I prefer CType whenever I'm dealing with enum values
JaredPar 13.10.2009 19:54:32
@Eric: a DirectCast should be used when an object is of a given type, and you are casting it to that type. A string is not an Enum, and neither is an integer. If you want to cast to an integer first, that might make your code more clear, but using DirectCast will just confuse things.
jmoreno 15.06.2017 16:46:22