2012-07-03 52 views
12

Trong VB.NET, tôi phải so sánh một số đối tượng trong câu lệnh select case.Chọn Case với toán tử "Is"

select case sử dụng = theo mặc định và điều này không được xác định cho đối tượng, lỗi biên dịch sẽ được ném.

Tôi hiện đang sử dụng workaround này:

Select Case True 
    Case sender Is StyleBoldButton 

    Case sender Is StyleUnderButton 

    Case sender Is StyleItalicButton 

End Select 

mà thực sự hoạt động.

Có điều gì đẹp hơn để xem và dễ hiểu hơn không?

+1

Có thể là cách tốt hơn khi sử dụng đa hình. Bạn đang làm gì với 'người gửi'? Có lẽ bạn có thể tóm tắt chức năng đó thành một thao tác đơn lẻ có thể hoạt động trên từng loại nút? Sau đó, bạn sẽ không cần 'Chọn' nhưng sẽ chỉ thực hiện thao tác đó bất kể loại nào? – David

+1

'Nếu người gửi là StyleBoldButton ElseIf .... End If'? Đẹp hơn để xem có lẽ không, dễ hiểu hơn có lẽ là có, vì bí quyết 'Chọn Case True' không phải là AFAIK được sử dụng rộng rãi trong VB.NET –

+0

@David Mmmhh ... Tôi cần đặt một biến khác cho mỗi nút. Tuy nhiên, BOLD và ITALIC là boolean, trong khi UNDERLINE là một loại enuberable. – Teejay

Trả lời

10

Bất cứ điều gì mà có toán tử so sánh điều kiện tiên quyết (=,> =, = <, vv) được định nghĩa là trò chơi công bằng cho Select Case. Đúng (hoặc sai), tài liệu tham khảo không được so sánh với = trong VB; người ta phải sử dụng Is. (Hoặc Object.Equals(objA As Object, objB As Object) - nhưng, thực sự, tại sao? Khi bạn có Is?)

Nhưng hãy xem Object equality behaves different in .NET - có lẽ cách VB ít gây nhầm lẫn? Dù sao, tôi nghĩ bạn bị mắc kẹt với thang If-ElseIf kể từ Select Case không làm Is. (Tốt, nó làm, nhưng đó là một khác nhau Is, giống như các it của HyperCard.) Tôi nghĩ rằng các bậc thang trông thông minh và dễ dàng để làm theo:

If sender Is StyleBoldButton Then 

ElseIf sender Is StyleUnderButton Then 

ElseIf sender Is StyleItalicButton Then 

Else 

End If 

Như bạn đã chỉ ra, mô hình Select Case True là một " OrElse "giải pháp ngắn mạch trong VB6 - một cách tuyệt vời để đáp ứng nhu cầu thực sự. Nhưng điều đó không cần thiết trong VB.NET. Trong tinh thần đó, có thể tốt hơn là sử dụng các mẫu thiết kế phù hợp hơn với các phương pháp hay nhất được mong đợi của một ngôn ngữ hướng đối tượng. Ví dụ, như Denis Troller đã đề xuất, tại sao không cho mỗi nút xử lý sự kiện của riêng mình?

Nhưng nếu bạn nhấn mạnh vào một cái gì đó giống như một Chọn Is-thể, đây là một cái gì đó tôi có lẽ sẽ không sử dụng bản thân mình:

With sender 
    If .Equals(StyleBoldButton) Then 

    ElseIf .Equals(StyleUnderButton) Then 

    ElseIf .Equals(StyleItalicButton) Then 

    Else 

    End If 
End With 

Ở đây tôi đang trông chờ vào .Equals để làm việc như C# == khi phải đối mặt với hai loại object để so sánh (xem http://visualstudiomagazine.com/articles/2011/02/01/equality-in-net.aspx). Vẻ đẹp của điều này là sender chỉ được đề cập một lần; tuy nhiên, có tất cả số này ElseIf .Equals(...) Then bạn sẽ phải nhập cho từng "Case".

Một cách khác tôi sẽ không sử dụng bản thân mình đang sử dụng GetHashCode():

Select Case sender.GetHashCode() 

    Case StyleBoldButton.GetHashCode() 

    Case StyleUnderButton.GetHashCode() 

    Case StyleItalicButton.GetHashCode() 

    Case Else 

End Select 

Ở đây tôi đang trông chờ vào những gì (rất) ít tôi biết GetHashCode() để duy nhất (đủ) xác định các điều khiển. (Xem Default implementation for Object.GetHashCode()).

+1

Có lẽ câu trả lời hay nhất cho câu hỏi của tôi là "Bạn không thể". Nhưng giải pháp của bạn là tốt :) – Teejay

+0

GetHashCode không nên dựa vào để xác định một đối tượng. Mã băm có thể giống nhau cho các đối tượng khác nhau. – jo0ls

-1

Ít súc tích, nhưng nhiều hơn nữa có thể đọc được:

if typeof(sender) is StyleBoldButton then 

elseif typeof(sender) is StyleUnderButton then 

elseif typeof(sender) is StyleItalicButton then 

else 

end if 
+2

Tôi tin OP đã hỏi về (cú pháp đường cho) so sánh các tham chiếu (các thể hiện của các đối tượng), không phải kiểu (các lớp đối tượng). Bên cạnh đó, một bậc thang If-Then-ElseIf đã được đề xuất trong các bình luận ở trên. – rskar

+0

@rskar Chính xác, tôi cần so sánh tài liệu tham khảo, không phải loại. BTW, trong trường hợp so sánh kiểu, typeof (người gửi) .toString() có lẽ là cách tốt nhất. – 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

Bạn có thể giải thích cách điều này cải thiện về giải pháp riêng của OP không? –

4

Tôi vừa gặp phải vấn đề tương tự này.Sau khi nhìn thấy một bưu chính, bài này tôi đến giải pháp này cho bản thân mình và tôi muốn chia sẻ trong trường hợp ai đó ra có thực sự muốn sử dụng Select Case như tôi đã làm :)

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

     Case StyleUnderButton.Name 

     Case StyleItalicButton.Name 

    End Select 

Cập nhật 6-16-16: Đã xóa "Is =" vì nó không cần thiết.

Cập nhật 8-27-16: Đã thay đổi cách sử dụng chuỗi để sử dụng .Name để theo dõi lỗi tốt hơn.

+0

'Case Is =" StyleBoldButton "' cung cấp cho bạn hơn 'Case" StyleBoldButton "' là gì? 'Is' là không cần thiết và do đó không liên quan đến câu hỏi. –

+0

Bởi vì bộ não của tôi bị kẹt trên giải pháp OPs so sánh đối tượng thay vì nhận ra rằng giải pháp của tôi là so sánh chuỗi nên tôi đặt toán tử Is vào đó mà không thực sự nghĩ về nó. – Jeffrey

+0

Ít nhất hãy sử dụng 'Case StyleBoldButton.Name' để bạn không nhận được kết quả không mong muốn nếu (hoặc đúng hơn khi) tên thay đổi. – NiKiZe

Các vấn đề liên quan