Отличия Directcast и Ctype от перечислений

 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

Почему CType работает, а DirectCast - не с одинаковым синтаксисом? Но если я перекину selectedValue на int до того, как DirectCast, то он заработает.

С Уважением

_Eric


person Eric    schedule 13.10.2009    source источник


Ответы (1)


Причина в том, что CType и DirectCast - это принципиально разные операции.

DirectCast - это механизм приведения в VB.Net, который позволяет выполнять только преобразования, определенные CLR. Он даже более строг, чем версия C # приведения типов, поскольку не учитывает пользовательские преобразования.

CType - это механизм лексического приведения. Он учитывает правила CLR, определенные пользователем преобразования и преобразования, определенные VB.Net. Короче говоря, он будет делать все возможное, чтобы создать допустимое преобразование объекта в указанный тип.

В этом конкретном случае вы пытаетесь преобразовать значение в Enum, которое не имеет определенного преобразования CLR, и, следовательно, это не удается. Однако среда выполнения VB.Net смогла найти лексическое преобразование для решения этой проблемы.

Здесь есть достойное обсуждение различий:

person JaredPar    schedule 13.10.2009
comment
Спасибо. Что было бы лучше всего в этом отношении? Явное приведение selectedValue к типу int и прямому преобразованию (# 2) или просто Ctype (# 3) - person Eric; 13.10.2009
comment
Я предпочитаю CType всякий раз, когда имею дело со значениями перечисления - person JaredPar; 13.10.2009
comment
@Eric: DirectCast следует использовать, когда объект имеет данный тип, и вы приводите его к этому типу. Строка не является Enum и не является целым числом. Если вы хотите сначала привести к целому числу, это может сделать ваш код более понятным, но использование DirectCast просто запутает ситуацию. - person jmoreno; 15.06.2017