Подтвердить что ты не робот

Выбрать случай с оператором "Is"

В VB.NET мне приходится сравнивать некоторые объекты в инструкции select case.

Так как select case по умолчанию использует оператор =, и это не определено для объектов, генерируется ошибка компиляции.

В настоящее время я использую это обходное решение:

Select Case True
    Case sender Is StyleBoldButton

    Case sender Is StyleUnderButton

    Case sender Is StyleItalicButton

End Select

который действительно работает.

Есть ли что-то красивое, чтобы видеть и более понятно?

4b9b3361

Ответ 1

Все, что имеет необходимые операторы сравнения (=, > =, <= и т.д.), является справедливой игрой для Select Case. Правильно (или ошибочно) ссылки просто не сравниваются с = в VB; нужно использовать Is. (Или Object.Equals(objA As Object, objB As Object) - но, действительно, почему? Когда у вас есть Is?)

Но посмотрите на Идентификация объекта ведет себя по-другому в .NET - возможно, способ VB менее запутан? Как бы то ни было, я думаю, что вы застряли с лестницей If-ElseIf, поскольку Select Case не выполняет Is. (ну, да, но это другое Is, больше похожее на it Hypercard.) Я думаю, что лестница выглядит умной и легкой:

If sender Is StyleBoldButton Then 

ElseIf sender Is StyleUnderButton Then

ElseIf sender Is StyleItalicButton Then

Else

End If 

Как вы уже отметили, шаблон Select Case True - это временное решение короткого замыкания "OrElse" в VB6 - неудобный способ удовлетворить реальную потребность. Но это не нужно в VB.NET. В этом духе, возможно, лучше использовать шаблоны проектирования в соответствии с лучшими практиками, ожидаемыми от объектно-ориентированного языка. Например, как предложил Денис Тролльер, почему бы не дать каждой кнопке собственный обработчик событий?

Но если вы настаиваете на чем-то вроде Is-able Select, здесь я, вероятно, не буду использовать себя:

With sender
    If .Equals(StyleBoldButton) Then

    ElseIf .Equals(StyleUnderButton) Then

    ElseIf .Equals(StyleItalicButton) Then

    Else

    End If
End With

Здесь я рассчитываю на .Equals работать как С# ==, когда сталкиваются с двумя типами object для сравнения (см. http://visualstudiomagazine.com/articles/2011/02/01/equality-in-net.aspx). Красота этого заключается в том, что sender упоминается только один раз; однако все это ElseIf .Equals( ... ) Then вам придется вводить для каждого "случая".

Другим способом, который я не буду использовать сам, является использование GetHashCode():

Select Case sender.GetHashCode()

    Case StyleBoldButton.GetHashCode()

    Case StyleUnderButton.GetHashCode()

    Case StyleItalicButton.GetHashCode()

    Case Else

End Select

Здесь я рассчитываю на то, что (очень) немного знаю о GetHashCode(), чтобы однозначно (достаточно) идентифицировать эти элементы управления. (См. Реализация по умолчанию для Object.GetHashCode()).

Ответ 2

Я только наткнулся на эту же проблему. Увидев еще одну запись и этот пост, я пришел к этому решению для себя, и я хотел поделиться тем, что кто-то действительно захотел использовать Select Case, как я:)

    Select Case DirectCast(sender, Button).Name
        Case StyleBoldButton.Name

        Case StyleUnderButton.Name

        Case StyleItalicButton.Name

    End Select

Обновление 6-16-16: Удалено "Is =", потому что это не нужно.

Обновление 8-27-16: Изменено использование строк для использования .Name для лучшего отслеживания ошибок.

Ответ 3

Менее кратким, но более читаемым:

if typeof(sender) is StyleBoldButton then

elseif typeof(sender) is StyleUnderButton then

elseif typeof(sender) is StyleItalicButton then

else

end if

Ответ 4

 Private Sub btnNum_Click(sender As Object, e As EventArgs) Handles btnNum0.Click, btnNum1.Click, btnNum2.Click, btnNum3.Click, btnNum4.Click, btnNum5.Click, btnNum6.Click, btnNum7.Click, btnNum8.Click, btnNum9.Click, btnDicemalPoint.Click, btnNumClear.Click, btnExit.Click
        If result = "0" Then
            result = ""
        End If
        Select Case True
            Case sender Is btnNum0
                If result <> "0" Then
                    result = result & "0"
                End If
            Case sender Is btnNum1
                result = result & "1"
            Case sender Is btnNum2
                result = result & "2"
            Case sender Is btnNum3
                result = result & "3"
            Case sender Is btnNum4
                result = result & "4"
            Case sender Is btnNum5
                result = result & "5"
            Case sender Is btnNum6
                result = result & "6"
            Case sender Is btnNum7
                result = result & "7"
            Case sender Is btnNum8
                result = result & "8"
            Case sender Is btnNum9
                result = result & "9"
            Case sender Is btnDicemalPoint
                If String.IsNullOrEmpty(result.ToString) Then
                    result = result & "0."
                ElseIf Not result.ToString.Contains(".") Then
                    result = result & "."
                End If
            Case sender Is btnNumClear
                result = 0
            Case sender Is btnExit
                Me.Close()
        End Select
End Sub