13
 Public Enum Fruit
    Red_Apple = 1
    Oranges
    Ripe_Banana
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, "_", " "))
    Next
    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

Regards

_Eric

bdukes
  • 152,002
  • 23
  • 148
  • 175
Eric
  • 3,027
  • 6
  • 29
  • 34

1 Answers1

22

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:

bdukes
  • 152,002
  • 23
  • 148
  • 175
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    Thanks. What would be the best practice on this? Explicit cast the selectedValue to an int and directcast(#2), or just Ctype(#3) – Eric Oct 13 '09 at 19:52
  • I prefer CType whenever I'm dealing with enum values – JaredPar Oct 13 '09 at 19:54
  • 1
    @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 Jun 15 '17 at 16:46