Directcast & Ctype differences with enums
Asked Answered
A

1

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

Argyll answered 13/10, 2009 at 18:49 Comment(0)
B
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:

Bacterin answered 13/10, 2009 at 19:4 Comment(3)
Thanks. What would be the best practice on this? Explicit cast the selectedValue to an int and directcast(#2), or just Ctype(#3)Argyll
I prefer CType whenever I'm dealing with enum valuesBacterin
@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.Revulsive

© 2022 - 2024 — McMap. All rights reserved.