2009-10-13 4 views
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 

Почему CType работы и DirectCast не с тем же синтаксисом? Тем не менее, если бы я бросил selectedValue к int, прежде чем я DirectCast, то он работаетDirectCast и CTYPE различие с перечислениями

С уважением

_Eric

ответ

19

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

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

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

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

Порядочный обсуждение различий существует здесь:

+1

Спасибо. Какая была бы лучшая практика? Явное выделение selectedValue для int и directcast (# 2) или просто Ctype (# 3) – Eric

+0

Я предпочитаю CType всякий раз, когда я имею дело с значениями перечисления – JaredPar

+0

@ Эрик: DirectCast следует использовать, когда объект имеет данный тип , и вы отбрасываете его на этот тип. Строка не является Enum, и ни одно из них не является целым числом. Если вы хотите сначала перенести в целое число, это может сделать ваш код более понятным, но использование DirectCast просто смутит. – jmoreno