2012-07-03 19 views
12

W VB.NET, muszę porównać niektóre obiekty w oświadczeniu select case.Wybierz skrzynkę z operatorem "Jest"

Od select case domyślnie używa operatora = i nie jest to zdefiniowane dla obiektów, zgłaszany jest błąd kompilacji.

I obecnie korzystać z tego rozwiązania:

Select Case True 
    Case sender Is StyleBoldButton 

    Case sender Is StyleUnderButton 

    Case sender Is StyleItalicButton 

End Select 

który faktycznie działa.

Czy jest coś ładniejszego do obejrzenia i bardziej zrozumiałego?

+1

Prawdopodobnie istnieje lepszy sposób użycia polimorfizmu. Co właściwie robisz z 'nadawcą'? Może możesz zlikwidować tę funkcjonalność do pojedynczej operacji, która działałaby na każdym typie przycisku? W takim razie nie potrzebujesz "Wybierz", ale po prostu wykonasz tę operację niezależnie od typu? – David

+1

'Jeśli nadawcą jest StyleBoldButton ElseIf .... End If'? Lepsze, aby zobaczyć, może nie, bardziej zrozumiałe prawdopodobnie tak, ponieważ sztuczka 'Select Case True' nie jest AFAIK bardzo szeroko stosowana w VB.NET –

+0

@ David Mmmhh ... Muszę ustawić inną zmienną dla każdego przycisku. Ale BOLD i ITALIC to boolean, podczas gdy UNDERLINE to gatunek uniwersalny. – Teejay

Odpowiedz

10

Wszystko, co ma wymagane operatorów porównania (=,> =, = <, etc.) zdefiniowany jest uczciwa gra dla Select Case. Słusznie (lub niesłusznie), odniesienia nie są porównywane z = w VB; należy użyć Is. (Lub Object.Equals(objA As Object, objB As Object) - ale, naprawdę, dlaczego? Kiedy masz Is?)

Ale spójrz na Object equality behaves different in .NET - być może sposób VB jest mniej mylący? Cokolwiek, myślę, że utknąłeś w drabinie If-ElseIf od Select Case, nie robisz Is. (Dobrze, że nie, ale to już zupełnie inna Is, bardziej jak it z HyperCard.) Myślę, że drabina wygląda elegancki i łatwy do naśladowania:

If sender Is StyleBoldButton Then 

ElseIf sender Is StyleUnderButton Then 

ElseIf sender Is StyleItalicButton Then 

Else 

End If 

Jak podkreśliło, wzór Select Case True jest " Orélse "obejście zwarciowe w VB6 - niewygodny sposób na zaspokojenie prawdziwej potrzeby. Ale to nie jest potrzebne w VB.NET. W tym duchu, może lepiej jest używać wzorców projektowych bardziej zgodnie z najlepszymi praktykami, jakich można oczekiwać od języka zorientowanego obiektowo. Na przykład, jak zasugerował Denis Troller, czemu nie dać każdemu przyciskowi własnego programu obsługi zdarzeń?

Ale jeśli nalegać na coś takiego IS-stanie Select, oto coś, co prawdopodobnie nie będzie używać sobie:

With sender 
    If .Equals(StyleBoldButton) Then 

    ElseIf .Equals(StyleUnderButton) Then 

    ElseIf .Equals(StyleItalicButton) Then 

    Else 

    End If 
End With 

Tutaj liczę na .Equals pracować jak C# == w obliczu dwa typy do porównania (zobacz http://visualstudiomagazine.com/articles/2011/02/01/equality-in-net.aspx). Piękno tego jest takie, że sender wspomniano tylko raz; jednak jest wszystko to ElseIf .Equals(...) Then, które będziesz musiał wpisać dla każdego "Przypadku".

Innym sposobem nie użyje się używa GetHashCode():

Select Case sender.GetHashCode() 

    Case StyleBoldButton.GetHashCode() 

    Case StyleUnderButton.GetHashCode() 

    Case StyleItalicButton.GetHashCode() 

    Case Else 

End Select 

Tutaj liczę na to, co (bardzo) mało znam GetHashCode() jednoznacznie (wystarczająco) zidentyfikować te kontrole. (Patrz Default implementation for Object.GetHashCode()).

+1

Prawdopodobnie najlepszą odpowiedzią na moje pytanie byłoby "Nie możesz". Ale twoje rozwiązania są w porządku :) – Teejay

+0

GetHashCode nie powinien być używany do identyfikacji obiektu. Hashcode może być taki sam dla różnych obiektów. – jo0ls

-1

Mniej zwięzły, ale o wiele bardziej czytelny:

if typeof(sender) is StyleBoldButton then 

elseif typeof(sender) is StyleUnderButton then 

elseif typeof(sender) is StyleItalicButton then 

else 

end if 
+2

Wierzę, że OP pytał o (syntaktyczny cukier za) porównując odniesienia (wystąpienia obiektów), a nie typy (klasy obiektów). Poza tym drabina If-Then-ElseIf była już zasugerowana w komentarzach powyżej. – rskar

+0

@rskar Dokładnie, muszę porównać odniesienia, a nie typy. BTW, w przypadku porównywania typów, typeof (nadawca) .toString() jest prawdopodobnie najlepszym sposobem. – Teejay

-2
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 
+3

Czy możesz wyjaśnić, w jaki sposób poprawia to własne rozwiązanie OP? –

4

Po prostu natknąłem się na ten sam problem.Po obejrzeniu kolejny post i ten post doszedłem do tego rozwiązania dla siebie i chciałem podzielić się w przypadku gdy ktoś tam naprawdę chciał wykorzystać Select Case jak ja :)

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

     Case StyleUnderButton.Name 

     Case StyleItalicButton.Name 

    End Select 

Aktualizacja 16.06.16: Usunięto "Is =", ponieważ było niepotrzebne.

Aktualizacja 8-27-16: Zmieniono użycie ciągów do użycia. Nazwa dla lepszego śledzenia błędów.

+0

Co to jest "Case Is =" StyleBoldButton "' daje ponad Case "StyleBoldButton" '? Określenie "jest" jest niepotrzebne, a zatem nie ma znaczenia dla pytania. –

+0

Ponieważ mój mózg utknął na porównawczym rozwiązaniu problemu z obiektami, zamiast zdać sobie sprawę, że moje rozwiązanie było porównaniem ciągów, więc umieściłem tam operatora Is, nie zastanawiając się nad tym. – Jeffrey

+0

Zamiast tego użyj zamiast tego 'Case StyleBoldButton.Name', aby uzyskać nieoczekiwane wyniki, jeśli (lub raczej kiedy) nazwa się zmieni. – NiKiZe

Powiązane problemy