Các tính năng ẩn của VB.NET?


121

Tôi đã tìm hiểu khá kỹ về cách duyệt qua Các tính năng ẩn của C # và rất ngạc nhiên khi tôi không thể tìm thấy thứ gì đó tương tự cho VB.NET.

Vậy một số tính năng ẩn hoặc ít được biết đến của nó là gì?

Câu trả lời:


128

Các Exception Whenkhoản chưa được biết đến.

Xem xét điều này:

Public Sub Login(host as string, user as String, password as string, _
                            Optional bRetry as Boolean = False)
Try
   ssh.Connect(host, user, password)
Catch ex as TimeoutException When Not bRetry
   ''//Try again, but only once.
   Login(host, user, password, True)
Catch ex as TimeoutException
   ''//Log exception
End Try
End Sub

9
hữu ích nếu bạn muốn bắt một SQLException cụ thể, nói -2 mà nếu tôi nhớ chính xác là thời gian chờ mạng: Catch ex như SQLException nơi ex.code = -2
Pondidum

Chà! Tôi vừa đọc nó và đưa nó vào sử dụng ngay lập tức để đơn giản hóa khối try / catch mà tôi vừa viết tuần trước. Tôi chưa bao giờ mới tồn tại điều này.
John M Gant

1
1 Và đây là nơi mà các đội CLR NET viết blog giải thích lý do tại sao bộ lọc ngoại lệ có ích blogs.msdn.com/clrteam/archive/2009/02/05/...
MarkJ

5
Điều này không chỉ bị ẩn mà còn không có trong C #.
Cheeso

82

Tùy chỉnh Enums

Một trong những tính năng ẩn thực sự của VB là completionlistthẻ tài liệu XML có thể được sử dụng để tạo Enumcác kiểu giống riêng với chức năng mở rộng. Tuy nhiên, tính năng này không hoạt động trong C #.

Một ví dụ từ mã gần đây của tôi:

'
''' <completionlist cref="RuleTemplates"/>
Public Class Rule
    Private ReadOnly m_Expression As String
    Private ReadOnly m_Options As RegexOptions

    Public Sub New(ByVal expression As String)
        Me.New(expression, RegexOptions.None)
    End Sub

    Public Sub New(ByVal expression As String, ByVal options As RegexOptions)
        m_Expression = expression
        m_options = options
    End Sub

    Public ReadOnly Property Expression() As String
        Get
            Return m_Expression
        End Get
    End Property

    Public ReadOnly Property Options() As RegexOptions
        Get
            Return m_Options
        End Get
    End Property
End Class

Public NotInheritable Class RuleTemplates
    Public Shared ReadOnly Whitespace As New Rule("\s+")
    Public Shared ReadOnly Identifier As New Rule("\w+")
    Public Shared ReadOnly [String] As New Rule("""([^""]|"""")*""")
End Class

Bây giờ, khi gán giá trị cho một biến được khai báo là Rule, IDE cung cấp danh sách IntelliSense về các giá trị có thể từ đó RuleTemplates.

/BIÊN TẬP:

Vì đây là một tính năng phụ thuộc vào IDE, thật khó để hiển thị nó trông như thế nào khi bạn sử dụng nó nhưng tôi sẽ chỉ sử dụng ảnh chụp màn hình:

Danh sách hoàn thành đang hoạt động http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

Trên thực tế, IntelliSense giống 100% với những gì bạn nhận được khi sử dụng Enum.


Thật thú vị - bạn có thể cho một ví dụ về cách thức này trông như thế nào khi bạn tiêu thụ nó?
Brian MacKay

Có vẻ như ai đó vẫn có thể tạo quy tắc của riêng họ bằng cách gọi trực tiếp hàm tạo Quy tắc? Nếu vậy, và nếu bạn muốn dừng việc này, bạn có thể khai báo hàm tạo là "Bạn" trong thư viện của mình không?
Joel Coehoorn 07/10/08

Joel, trong mã ví dụ của tôi, tôi thực sự không cấm điều này. Thay vào đó, tôi cung cấp cho người dùng một số quy tắc chung và cho phép tạo các quy tắc riêng, chuyên biệt. Tất nhiên, bạn có thể ngăn chặn điều này bằng cách đánh dấu hàm tạo là friendhoặc bằng cách sử dụng cùng một lớp với enum: Rulethay vì RuleTemplate.
Konrad Rudolph

có một nơi nào đó với một danh sách các sử dụng thuộc tính hữu ích ẩn? cái này nhìn trực diện thì có vẻ khó tin, nhưng tôi vẫn chưa chắc mình sẽ sử dụng nó ở đâu hoặc liệu nó có thể giải quyết một chuôi chính trong một số trường hợp mà không có khả năng bị hạn chế chung đối với enums.
Maslow

@Maslow: không có thuộc tính nào liên quan ở đây. Đó là một bình luận xml.
Joel Coehoorn

49

Bạn có nhận thấy toán tử so sánh Like không?

Dim b As Boolean = "file.txt" Like "*.txt"

Thêm từ MSDN

Dim testCheck As Boolean

' The following statement returns True (does "F" satisfy "F"?)'
testCheck = "F" Like "F"

' The following statement returns False for Option Compare Binary'
'    and True for Option Compare Text (does "F" satisfy "f"?)'
testCheck = "F" Like "f"

' The following statement returns False (does "F" satisfy "FFF"?)'
testCheck = "F" Like "FFF"

' The following statement returns True (does "aBBBa" have an "a" at the'
'    beginning, an "a" at the end, and any number of characters in '
'    between?)'
testCheck = "aBBBa" Like "a*a"

' The following statement returns True (does "F" occur in the set of'
'    characters from "A" through "Z"?)'
testCheck = "F" Like "[A-Z]"

' The following statement returns False (does "F" NOT occur in the '
'    set of characters from "A" through "Z"?)'
testCheck = "F" Like "[!A-Z]"

' The following statement returns True (does "a2a" begin and end with'
'    an "a" and have any single-digit number in between?)'
testCheck = "a2a" Like "a#a"

' The following statement returns True (does "aM5b" begin with an "a",'
'    followed by any character from the set "L" through "P", followed'
'    by any single-digit number, and end with any character NOT in'
'    the character set "c" through "e"?)'
testCheck = "aM5b" Like "a[L-P]#[!c-e]"

' The following statement returns True (does "BAT123khg" begin with a'
'    "B", followed by any single character, followed by a "T", and end'
'    with zero or more characters of any type?)'
testCheck = "BAT123khg" Like "B?T*"

' The following statement returns False (does "CAT123khg" begin with'
'    a "B", followed by any single character, followed by a "T", and'
'    end with zero or more characters of any type?)'
testCheck = "CAT123khg" Like "B?T*"

3
đợi đã, gì? Đó là điều mới mẻ đối với tôi! Hmm, đó là một helluva tốt hơn nhiều so với giải pháp thay thế với thao tác chuỗi VB.NET: D
STW

.. !! Tôi không biết điều đó mặc dù tôi đã làm việc trên một số dự án vb.net! Tính năng thú vị ...
Meta-Knight

chaooooooooooooooooooooooow! cảm ơn! thật là tuyệt! nó có hoạt động trong ELinq, DLinq không? XLinq thì sao?
Shimmy Weitzhandler

@dotjoe Hmm? Không có gì 'lười biếng' về những quả cầu này.
Josh Lee

Làm thế nào điều này thực hiện, những gì đang xảy ra dưới mui xe? Nó có phải là từ đồng nghĩa với thư viện reg ex không?
brumScouse

48

Typedefs

VB biết một loại nguyên thủy typedefthông qua Importbí danh:

Imports S = System.String

Dim x As S = "Hello"

Điều này hữu ích hơn khi được sử dụng kết hợp với các loại chung:

Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)

2
vui lòng hiển thị một ví dụ từ Nhập không được công nhận trong IDE của tôi.
Shimmy Weitzhandler

5
Importsnó nên được. ;-) Bằng cách nào đó, lỗi này đã không bị phát hiện (và thu được 28 lượt bình chọn) trong gần một năm.
Konrad Rudolph

Tôi luôn tự hỏi làm thế nào tôi có thể tạo một "loại" mới với các giá trị mặc định cho một loại chung! Mát mẻ!
eidylon

3
Nhập khẩu, nhập khẩu, nhập khẩu, bất cứ điều gì! Sheesh, bạn nghĩ rằng chúng tôi đã đọc những bài đăng này trước khi chúng tôi tán thành chúng!
MarkJ

Tuyệt vời cho việc sử dụng trong các thử nghiệm xUnit visual studio tứcImports Assert = xUnit.Assert
wheelibin

45

Oh! và đừng quên XML Literals .

Dim contact2 = _
        <contact>
          <name>Patrick Hines</name>
          <%= From p In phoneNumbers2 _
            Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
          %>
        </contact>

Đó là những gì tôi sẽ nói. Trên thực tế, tôi đã sử dụng các ký tự XML cho một mục đích mà nó không được dự định. Tôi sử dụng nó để tạo ra javascript ... swortham.blogspot.com/2009/03/vb-2008.html
Steve Wortham

9
Trong số những thứ khác, bạn có thể sử dụng XML Literals để thoát khỏi chuỗi xấu xí, ví dụ: khi bạn đang sử dụng các chuỗi chứa dấu ngoặc kép. Chỉ cần đặt chuỗi bên trong một XML Literal và gọi Giá trị, như sau: <string>This string contains "quotes" and it's OK.</string>.Value (Tôi thấy điều này đặc biệt hữu ích khi viết các bài kiểm tra về phân tích cú pháp tệp CSV trong đó mọi trường đều nằm trong dấu ngoặc kép. Sẽ không vui nếu thoát tất cả các dấu ngoặc kép đó bằng tay trong đường kiểm tra.)
Ryan Lundy

2
@Kyralessa: +1, nhận xét tuyệt vời. Trên thực tế, đó cũng là một cách tuyệt vời để chỉ định các chuỗi nhiều dòng (các câu lệnh SQL ôm, v.v.).
Heinzi

Nội tuyến XML là một trong những tính năng VB.NET tồi tệ nhất từng được hình thành. Sự thật không có cơ sở.
Grant Thomas

39

Khởi tạo đối tượng cũng ở trong đó!

Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}

1
Tôi không thể tin rằng họ đã đi với dấu ngoặc nhọn. Chúng tôi đã có câu lệnh With .. họ có thể sử dụng lại cú pháp đó.
Sam Axe

2
Tôi biết, nó được làm chỉ để cho bạn thấy rằng không có cảnh sát trên đường ... lol JK
Shimmy Weitzhandler

4
Điều gì sẽ xảy ra khi tất cả những người viết trình biên dịch đều là những nhà lập trình C / C ++. Họ tiếp tục chuyển cú pháp C sang các ngôn ngữ khác bởi vì họ không thể hiểu được điều gì tốt hơn.
RBarryYoung 19/09/09

38

DirectCast

DirectCastlà một điều kỳ diệu. Bề ngoài, nó hoạt động tương tự như CTypetoán tử ở chỗ nó chuyển đổi một đối tượng từ kiểu này thành kiểu khác. Tuy nhiên, nó hoạt động theo một bộ quy tắc chặt chẽ hơn nhiều. CTypeDo đó, hành vi thực tế của nó thường không rõ ràng và hoàn toàn không rõ ràng loại chuyển đổi nào được thực hiện.

DirectCast chỉ hỗ trợ hai hoạt động riêng biệt:

  • Mở hộp một loại giá trị và
  • upcasting trong hệ thống phân cấp lớp.

Bất kỳ quá trình ép kiểu nào khác sẽ không hoạt động (ví dụ: cố gắng mở hộp một Integerđến a Double) và sẽ dẫn đến lỗi thời gian biên dịch / thời gian chạy (tùy thuộc vào tình huống và những gì có thể được phát hiện bằng cách kiểm tra kiểu tĩnh). Do đó tôi sử dụngDirectCast bất cứ khi nào có thể, vì điều này nắm bắt được ý định của tôi tốt nhất: tùy thuộc vào tình huống, tôi muốn mở hộp một giá trị thuộc loại đã biết hoặc thực hiện một upcast. Kết thúc câu chuyện.

CTypeMặt khác, việc sử dụng khiến người đọc mã băn khoăn không biết lập trình viên thực sự có ý định gì vì nó giải quyết tất cả các loại hoạt động khác nhau, bao gồm cả việc gọi mã do người dùng xác định.

Tại sao đây là một tính năng ẩn? Nhóm VB đã xuất bản một hướng dẫn 1 không khuyến khích sử dụng DirectCast(mặc dù nó thực sự nhanh hơn!) Để làm cho mã thống nhất hơn. Tôi cho rằng đây là một hướng dẫn tồi cần được đảo ngược: Bất cứ khi nào có thể, hãy ưu tiên toán tử DirectCasttổng quát hơn CType. Nó làm cho mã rõ ràng hơn nhiều. CType, mặt khác, chỉ nên được gọi nếu điều này thực sự được dự định, tức là khi một CTypetoán tử thu hẹp (xem quá tải toán tử ) nên được gọi.


1) Tôi không thể tìm ra liên kết đến hướng dẫn nhưng tôi nhận thấy Paul Vick đã thực hiện nó (nhà phát triển trưởng của nhóm VB):

Trong thế giới thực, bạn hầu như không nhận ra sự khác biệt, vì vậy bạn cũng có thể sử dụng các toán tử chuyển đổi linh hoạt hơn như CType, CInt, v.v.


(EDIT bởi Zack: Tìm hiểu thêm tại đây: Tôi nên truyền như thế nào trong VB.NET? )


Tôi thực sự thích TryCast () hơn một chút. Nó sẽ không ném ra một ngoại lệ, chỉ trả về Không có gì nếu quá trình cast không thành công. Nếu bạn mong đợi quá trình truyền thường xuyên bị lỗi, nó sẽ nhanh hơn If TypeOf x Is T ... DirectCast (x, T) và chắc chắn nhanh hơn việc bắt ngoại lệ nếu DirectCast không thành công.
Bob King

6
DirectCast () và TryCast () là vô giá khi được sử dụng đúng cách như một cặp. DirectCast () nên được sử dụng nếu đối tượng đang được ép kiểu luôn được mong đợi là loại đích (nếu không, bạn sẽ gặp lỗi, một điều tốt vì đó là một tình huống không mong muốn). TryCast () nên được sử dụng nếu đối tượng được truyền thể thuộc loại đích hoặc một số loại đích. Sử dụng riêng một hoặc khác sẽ dẫn đến chi phí bổ sung (nếu typeof x là y thì directcast (x, y) không hiệu quả) hoặc để tránh các lỗi hợp lệ (sử dụng TryCast () cho các trường hợp đối tượng luôn phải là loại đích)
STW

Yoooder: Đúng 100%. Thật tiếc là tôi đã không đề cập đến TryCasthồi đó vì tôi chủ yếu phải lấy xương với việc sử dụng phổ biến CType.
Konrad Rudolph

@Maslow: tất nhiên là không, vì Enums là các kiểu giá trị và TryCastchỉ hoạt động trên các kiểu tham chiếu, theo tài liệu.
Konrad Rudolph

+1: Hì. Tôi phải thừa nhận rằng, tôi vừa đọc nó và nghĩ "Ồ đúng rồi, DirectCast, làm sao tôi quên được điều đó?" Và sau đó tôi sử dụng nó trên dòng mã tiếp theo của mình (vì tôi thực sự không thích CType).
RBarryYoung 19/09/09

37

If nhà điều hành có điều kiện và liên kết

Tôi không biết bạn gọi nó là ẩn như thế nào, nhưng hàm Iif ([biểu thức], [giá trị nếu đúng], [giá trị nếu sai]) As Object có thể đếm được.

Nó không bị ẩn nhiều đến mức không được dùng nữa ! VB 9 có Iftoán tử tốt hơn nhiều và hoạt động chính xác như toán tử điều kiện và liên kết của C # (tùy thuộc vào những gì bạn muốn):

Dim x = If(a = b, c, d)

Dim hello As String = Nothing
Dim y = If(hello, "World")

Đã chỉnh sửa để hiển thị một ví dụ khác:

Điều này sẽ hoạt động với If(), nhưng gây ra một ngoại lệ vớiIIf()

Dim x = If(b<>0,a/b,0)

Tốt, tôi không biết điều này! Tôi vừa mới sử dụng IIF ngày hôm qua nên tôi sẽ truy cập lại khối mã đó.
Sean Gough 19-08

4
Nói với VS 2005 rằng. Không phải tất cả chúng ta đều có thể làm việc với những gì mới nhất và tốt nhất.
Sam Erwin 19-08

3
@Slough, vớ vẩn. Phương thức này là kiểu an toàn 100% và nó trả về một đối tượng cùng kiểu với đối số (thứ hai và thứ ba) của nó. Ngoài ra, phải có sự chuyển đổi mở rộng giữa các đối số, nếu không sẽ xảy ra lỗi biên dịch vì các loại không khớp.
Konrad Rudolph

1
Vâng, IIf () của nó mà không phải là loại an toàn
Pondidum

2
@ Br.Bill Trên thực tế, nó hoàn toàn tương đương với :?toán tử C và Perl , nó không chỉ là một phiên bản đơn giản hóa.
Konrad Rudolph

32

Cái này là một cái tốt. Câu lệnh Select Case trong VB.Net rất mạnh mẽ.

Chắc chắn có tiêu chuẩn

Select Case Role
  Case "Admin"
         ''//Do X
  Case "Tester"
         ''//Do Y
  Case "Developer"
         ''//Do Z
  Case Else
       ''//Exception case
End Select

Nhưng còn nhiều ...

Bạn có thể làm phạm vi:

Select Case Amount
 Case Is < 0
    ''//What!!
 Case 0 To 15
   Shipping = 2.0
 Case 16 To 59
    Shipping = 5.87
 Case Is > 59
    Shipping = 12.50
 Case Else
    Shipping = 9.99
 End Select

Va thậm chi nhiêu hơn...

Bạn có thể (mặc dù có thể không phải là một ý kiến ​​hay) thực hiện kiểm tra boolean trên nhiều biến:

Select Case True
 Case a = b
    ''//Do X
 Case a = c
    ''//Do Y
 Case b = c
    ''//Do Z
 Case Else
   ''//Exception case
 End Select

5
Trên thực tế, bạn đã bỏ lỡ một vài: a) sử dụng "Chọn trường hợp đúng" để kiểm tra nhiều hơn một biến, b) sử dụng biểu mẫu "Trường hợp A, B, ..." và thậm chí c) áp dụng ":" cho trong- dòng lệnh thực thi với mệnh đề điều kiện (mặc dù nhiều người không thích điều này).
RBarryYoung 19/09/09

6
Vui lòng không sử dụng Chọn trường hợp Đúng. Chỉ cần sử dụng câu lệnh If.
Ryan Lundy

4
Tôi thấy Select Case True dễ đọc hơn nhiều so với một câu lệnh ifelse khổng lồ.
dwidel

Vấn đề với Select Case Truelà nó trông như thể nó đánh giá mỗi của Casebáo cáo và chạy mã cho mỗi người đó là sự thật. Nhưng trên thực tế, nó đánh giá từng cái một và chỉ chạy mã cho cái đầu tiên đúng. Cú pháp cho Ifrõ ràng hơn nhiều về vấn đề này ( If...Else If...Else If...Else).
Ryan Lundy

31

Một trình tiết kiệm thời gian chính mà tôi sử dụng mọi lúc là từ khóa Với :

With ReallyLongClassName
    .Property1 = Value1
    .Property2 = Value2
    ...
End With

Tôi chỉ không thích gõ nhiều hơn tôi phải!


Nhưng nó cũng tạo ra một số lỗi ẩn, đặc biệt là khi bạn có Với trong vòng Với
Varun Mahajan

2
Tôi thậm chí còn không biết bạn có thể đặt một Với ​​mới trong một Với ​​hiện có. Thật là cẩu thả!
Bob King

2Bob: nó không cẩu thả, tôi đề nghị .. nó chỉ là một cấu trúc ngôn ngữ được sử dụng cẩn thận. Đối với việc thiết lập nhiều thuộc tính trong các dòng liên tiếp, thật tuyệt vời, nhưng việc tìm một .Foo ngẫu nhiên trong một đoạn mã phức tạp và sau đó phải tìm kiếm các dòng với câu lệnh x ở trên không phải là cách sử dụng tốt tính năng này.
ChrisA

2
Chúc C # có cái này? Hay tôi đã ngủ và đó là câu trả lời trong C # tính năng ẩn đã có ...? ;-)
peSHIr

1
@Boo: Bạn nói đúng nhưng vẫn còn một điều phiền toái là bạn không thể thêm nó vào danh sách Watch.
Meta-Knight

31

Trình phân tích cú pháp CSV tốt nhất và dễ dàng:

Microsoft.VisualBasic.FileIO.TextFieldParser

Bằng cách thêm một tham chiếu đến Microsoft.VisualBasic, điều này có thể được sử dụng trong bất kỳ ngôn ngữ .Net nào khác, ví dụ: C #


5
+1 Thật kỳ lạ khi những người C # chạy đến FileHelpers mà không bao giờ xem xét điều này. Tôi chắc chắn rằng FileHelpers là tuyệt vời, nhưng nó là một phụ thuộc bên ngoài.
MarkJ

@MarkJ Tôi đoán đó là vì sự thiếu hiểu biết
Nathan Koop

Tôi đã cố gắng tìm kiếm lớp học này nhưng không bao giờ làm được, cảm ơn vì đã tạo ra nó!
pingoo


25

Các thành viên tĩnh trong các phương thức.

Ví dụ:

Function CleanString(byval input As String) As String
    Static pattern As New RegEx("...")

    return pattern.Replace(input, "")
End Function

Trong hàm trên, biểu thức chính quy mẫu sẽ chỉ được tạo một lần cho dù hàm được gọi bao nhiêu lần.

Một cách sử dụng khác là giữ một trường hợp "ngẫu nhiên" xung quanh:

Function GetNextRandom() As Integer
    Static r As New Random(getSeed())

    Return r.Next()
End Function 

Ngoài ra, điều này không giống như chỉ đơn giản khai báo nó là thành viên được chia sẻ của lớp; các mục được khai báo theo cách này cũng được đảm bảo an toàn theo chuỗi. Nó không quan trọng trong trường hợp này vì biểu thức sẽ không bao giờ thay đổi, nhưng có những người khác ở nơi nó có thể.


1
Một công dụng của điều này là giữ một bộ đếm sẽ tăng lên mỗi khi phương thức được gọi. Nếu biến được đánh dấu là Tĩnh, nó sẽ không được khởi động lại trên mỗi lần gọi phương thức; nó sẽ chỉ được khởi tạo trong lần gọi đầu tiên và sau đó sẽ giữ nguyên giá trị của nó.
Ryan Lundy

Đây là lý do tại sao các thành viên lớp tĩnh được đặt tên là "chia sẻ" trong VB.NET
Enrico Campidoglio

Static là dạng xấu trong VB.NET thậm chí nhiều hơn so với dạng VB cổ điển. Nên tránh các biến tĩnh bất cứ khi nào và bất cứ khi nào có thể.
Sam Axe

6
@Boo - đó là khá sâu. Lời biện minh của bạn là gì? Tôi nghĩ rằng các biến tĩnh rất hữu ích.
MarkJ

4
Static, được sử dụng như trong các ví dụ trên, cho phép một hình thức đóng gói duy nhất: các biến cấp lớp có phạm vi cấp phương thức. Nếu không có nó, bạn phải tạo một biến cấp độ lớp có thể truy cập được cho bất kỳ thành viên nào trong lớp, ngay cả khi bạn chỉ sử dụng nó trong một phương thức.
Ryan Lundy

25

Trong vb có sự khác biệt giữa các toán tử này:

/đang Double
\được Integerbỏ qua phần còn lại

Sub Main()
    Dim x = 9 / 5  
    Dim y = 9 \ 5  
    Console.WriteLine("item x of '{0}' equals to {1}", x.GetType.FullName, x)
    Console.WriteLine("item y of '{0}' equals to {1}", y.GetType.FullName, y)

    'Results:
    'item x of 'System.Double' equals to 1.8
    'item y of 'System.Int32' equals to 1
End Sub

1
tôi đã học được điều này một cách khó khăn khi cố gắng mò kim đáy bể hàng triệu dòng mã. chia đều so với số nguyên. Mẹo tốt!
Jason Irwin

23

Tôi thực sự thích Không gian tên "của tôi" được giới thiệu trong Visual Basic 2005. My là một lối tắt đến một số nhóm thông tin và chức năng. Nó cung cấp quyền truy cập nhanh chóng và trực quan vào các loại thông tin sau:

  • My.Computer : Truy cập vào thông tin liên quan đến máy tính như hệ thống tệp, mạng, thiết bị, thông tin hệ thống, v.v. Nó cung cấp quyền truy cập vào một số tài nguyên rất quan trọng bao gồm My.Computer.Network, My.Computer.FileSystem và My . Máy tính. Máy in.
  • Ứng dụng của tôi : Truy cập thông tin liên quan đến ứng dụng cụ thể như tên, phiên bản, thư mục hiện tại, v.v.
  • My.User : Truy cập thông tin liên quan đến người dùng đã xác thực hiện tại.
  • My.Resources : Quyền truy cập vào các tài nguyên được ứng dụng sử dụng nằm trong các tệp tài nguyên theo cách được đánh máy mạnh.
  • My.Settings : Truy cập vào cài đặt cấu hình của ứng dụng theo cách gõ mạnh.

Điều này thật tuyệt và mọi người chơi vb.net ngoài kia đều nên biết những thứ trong không gian tên của tôi, nó rất hữu ích.
dr. ác

Của tôi. * FTW :).
dr. ác

3
Nó khá hữu ích, nhưng tôi ghét cái tên ngu xuẩn. Nhắc tôi về điều này secretgeek.net/refactvb.asp
MarkJ

23

Sự kiện tùy chỉnh

Mặc dù hiếm khi hữu ích, việc xử lý sự kiện có thể được tùy chỉnh rất nhiều:

Public Class ApplePie
    Private ReadOnly m_BakedEvent As New List(Of EventHandler)()

    Custom Event Baked As EventHandler
        AddHandler(ByVal value As EventHandler)
            Console.WriteLine("Adding a new subscriber: {0}", value.Method)
            m_BakedEvent.Add(value)
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            Console.WriteLine("Removing subscriber: {0}", value.Method)
            m_BakedEvent.Remove(value)
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
            Console.WriteLine("{0} is raising an event.", sender)
            For Each ev In m_BakedEvent
                ev.Invoke(sender, e)
            Next
        End RaiseEvent
    End Event

    Public Sub Bake()
        ''// 1. Add ingredients
        ''// 2. Stir
        ''// 3. Put into oven (heated, not pre-heated!)
        ''// 4. Bake
        RaiseEvent Baked(Me, EventArgs.Empty)
        ''// 5. Digest
    End Sub
End Class

Điều này sau đó có thể được kiểm tra theo cách sau:

Module Module1
    Public Sub Foo(ByVal sender As Object, ByVal e As EventArgs)
        Console.WriteLine("Hmm, freshly baked apple pie.")
    End Sub

    Sub Main()
        Dim pie As New ApplePie()
        AddHandler pie.Baked, AddressOf Foo
        pie.Bake()
        RemoveHandler pie.Baked, AddressOf Foo
    End Sub
End Module

có vẻ thú vị, nhưng nếu tôi cần điều này, tôi nghĩ rằng tôi sẽ làm điều gì đó sai ;-). Nó chỉ có vẻ chống lại nguyên tắc KISS.
chrissie1

4
Nó thực sự, thực sự hữu ích khi bạn muốn đảm bảo mọi bồn rửa đều nhận được sự kiện ngay cả khi một hoặc nhiều trường hợp ngoại lệ.
Jonathan Allen

Một giá trị khác (tôi vừa đọc được trên trang MSDN) là nếu lớp của bạn ném nhiều sự kiện, bạn có thể buộc nó sử dụng bảng băm / từ điển làm vùng chứa, thay vì khai báo một trường cho mỗi sự kiện. msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
torial

Mát mẻ. Tôi nghĩ đây là một trong những tính năng tạo nên sự khác biệt giữa C # và VB.NET (như trong một cái có thể, nhưng cái kia không có cú pháp cho nó). Rất vui khi ít nhất biết tôi đã sai về mặt này.
peSHIr

21

Tôi vừa tìm thấy một bài báo nói về dấu "!" toán tử, còn được gọi là "toán tử tra cứu từ điển". Đây là đoạn trích từ bài viết tại: http://panopticoncentral.net/articles/902.aspx

Tên kỹ thuật cho! toán tử là "toán tử tra cứu từ điển." Từ điển là bất kỳ loại tập hợp nào được lập chỉ mục bằng một khóa chứ không phải số, giống như cách mà các mục nhập trong từ điển tiếng Anh được lập chỉ mục theo từ bạn muốn định nghĩa. Ví dụ phổ biến nhất về kiểu từ điển là System.Collections.Hashtable, cho phép bạn thêm các cặp (khóa, giá trị) vào bảng băm và sau đó truy xuất các giá trị bằng các khóa. Ví dụ: mã sau đây thêm ba mục nhập vào bảng băm và tìm một trong số chúng bằng cách sử dụng phím "Pork".

Dim Table As Hashtable = New Hashtable
Table("Orange") = "A fruit"
Table("Broccoli") = "A vegetable"
Table("Pork") = "A meat" 
Console.WriteLine(Table("Pork"))

Các ! toán tử có thể được sử dụng để tra cứu các giá trị từ bất kỳ loại từ điển nào lập chỉ mục các giá trị của nó bằng cách sử dụng chuỗi. Định danh sau dấu! được sử dụng làm chìa khóa trong thao tác tra cứu. Vì vậy, mã trên thay vào đó có thể được viết:

Dim Table As Hashtable = New Hashtable
Table!Orange = "A fruit"
Table!Broccoli = "A vegetable"
Table!Pork = "A meat"
Console.WriteLine(Table!Pork)

Ví dụ thứ hai hoàn toàn tương đương với ví dụ đầu tiên, nhưng trông đẹp hơn rất nhiều, ít nhất là đối với mắt tôi. Tôi thấy rằng có rất nhiều nơi mà! có thể được sử dụng, đặc biệt khi nói đến XML và web, nơi có rất nhiều bộ sưu tập được lập chỉ mục theo chuỗi. Một hạn chế đáng tiếc là điều sau! vẫn phải là một số nhận dạng hợp lệ, vì vậy nếu chuỗi bạn muốn sử dụng làm khóa có một số ký tự nhận dạng không hợp lệ trong đó, bạn không thể sử dụng! nhà điều hành. (Ví dụ: bạn không thể nói "Bảng! AB $ CD = 5" vì $ không hợp pháp trong số nhận dạng.) Trong VB6 trở về trước, bạn có thể sử dụng dấu ngoặc để thoát các số nhận dạng không hợp lệ (tức là "Bảng! [AB $ CD] "), nhưng khi chúng tôi bắt đầu sử dụng dấu ngoặc để thoát từ khóa, chúng tôi đã mất khả năng làm điều đó. Trong hầu hết các trường hợp,

Để thực sự mang tính kỹ thuật, x! Y hoạt động nếu x có thuộc tính mặc định lấy Chuỗi hoặc Đối tượng làm tham số. Trong trường hợp đó, x! Y được đổi thành x.DefaultProperty ("y"). Một lưu ý phụ thú vị là có một quy tắc đặc biệt trong ngữ pháp từ vựng của ngôn ngữ để làm cho tất cả điều này hoạt động. Các ! ký tự cũng được sử dụng như một ký tự kiểu trong ngôn ngữ và các ký tự kiểu được sử dụng trước các toán tử. Vì vậy, không có quy tắc đặc biệt, x! Y sẽ được quét dưới dạng "x! Y" thay vì "x! Y". May mắn thay, vì không có nơi nào trong ngôn ngữ mà hai định danh trong một hàng là hợp lệ, chúng tôi chỉ giới thiệu quy tắc nếu ký tự tiếp theo sau! là phần bắt đầu của một định danh, chúng tôi coi là! là một toán tử và không phải là một ký tự kiểu.


11
Đó là một trong những tính năng tôi đã sử dụng sau đó cố tình quên. Nó tiết kiệm một vài lần gõ phím nhưng làm rối loạn khả năng đọc và đánh dấu mã của tôi. lại quên ngay .... NOW
STW

3
Thú vị, nhưng không thực sự hữu ích. Đây có phải là loại công cụ mà nhóm VB làm việc thay vì thêm các tính năng bị thiếu như từ khóa lợi nhuận? : P
Meta-Knight

5
Tính năng này được thực hiện để tương thích ngược từ VB3 (AFAIK)
Eduardo Molteni

1
những lớp triển khai chỉ mục có khóa có giao diện chung mà chúng kế thừa không? như IKeyed giống như cách các vùng chứa được lập chỉ mục số nguyên triển khai IENumberable?
Maslow

2
Tính năng này cũng hoạt động với DataRows (tức là dr! ID) rất tiện dụng trong LINQ to DataSets.
Paul

19

Điều này được tích hợp sẵn và là một lợi thế nhất định so với C #. Khả năng thực hiện một Phương thức giao diện mà không cần phải sử dụng cùng một tên.

Nhu la:

Public Sub GetISCSIAdmInfo(ByRef xDoc As System.Xml.XmlDocument) Implements IUnix.GetISCSIInfo

End Sub

Tôi tin chắc rằng bạn có thể làm điều gì đó như thế này trong C #. Trong VB.NET, nó chỉ là bắt buộc, và trong C #, nó là tùy chọn?
Jesper Blad Jensen

5
Bạn cũng có thể đặt sub ở chế độ riêng tư, đây là một cách tuyệt vời để ẩn những thứ như lệnh gọi đến các phiên bản giao diện không dùng chung chung.
Craig Gidney

3
Nó có thể là một ý tưởng tốt. Ví dụ cổ điển sẽ là nếu bạn muốn một phương thức Đóng Công khai cũng hoạt động như việc triển khai Loại bỏ của bạn cho IDisposable.
MarkJ

1
Điều đó cũng khá hữu ích nếu bạn tình cờ triển khai hai giao diện có chung tên phương thức.
Eric Nicholson

Tôi đã thấy điều này và luôn ước rằng mình đã không làm như vậy. Không được phép.
FastAl

17

Buộc ByVal

Trong VB, nếu bạn đặt các đối số của mình trong một tập hợp thêm dấu ngoặc đơn, bạn có thể ghi đè khai báo ByRef của phương thức và biến nó thành một ByVal. Ví dụ: mã sau tạo ra 4, 5, 5 thay vì 4,5,6

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim R = 4
    Trace.WriteLine(R)
    Test(R)
    Trace.WriteLine(R)
    Test((R))
    Trace.WriteLine(R)
End Sub
Private Sub Test(ByRef i As Integer)
    i += 1
End Sub

Xem đối số không được sửa đổi bởi lệnh gọi thủ tục - Biến cơ bản


6
Ôi trời ... đó là một tính năng đáng chú ý, mặc dù tôi không nghĩ mình sẽ biết nó đang làm gì nếu tôi đọc nó trong mã của người khác. Nếu bạn phải nhận xét nó chỉ để biết nó đang làm gì, bạn cũng có thể đã thực hiện biến vứt bỏ để chuyển vào thay thế.
mattmc3

7
Đây thực sự là một tác dụng phụ của việc sử dụng dấu ngoặc đơn - Dấu ngoặc đơn tạo ra giá trị tạm thời của những gì bên trong, ngay cả khi chỉ là một mục. Hiệu ứng này đã GIẾT TÔI trong vb6 - Các lệnh gọi phụ không sử dụng parens, nhưng tôi đến từ C theo bản năng đưa parens vào. 6.0 đã làm nổ tung nhiều tham số, nhưng đối với một tham số phụ, nó vui vẻ chuyển một giá trị tạm thời và REFUSED để tôn vinh tôi 'byref'. Diễn ra khoảng 3 năm một lần, khoảng thời gian mà tôi đã quên đi sự việc vừa rồi.
FastAl

16

Truyền các tham số theo tên và do đó sắp xếp lại chúng

Sub MyFunc(Optional msg as String= "", Optional displayOrder As integer = 0)

    'Do stuff

End function

Sử dụng:

Module Module1

    Sub Main()

        MyFunc() 'No params specified

    End Sub

End Module

Cũng có thể được gọi bằng cách sử dụng đặc tả tham số ": =" theo bất kỳ thứ tự nào:

MyFunc(displayOrder:=10, msg:="mystring")

Wow, điều này thật tuyệt! Tôi thấy điều này khi sử dụng Dịch vụ Web, v.v. nhưng tôi không biết bạn có thể thực hiện điều này bằng bất kỳ phương pháp bình thường nào.
RichC

2
Chắc chắn là một công cụ rất tiện dụng khi bạn gặp một phương thức có quá nhiều đối số. Tôi cố gắng đặt tên cho từng tham số và đặt tên: = value trên dòng riêng của nó. Nó trực quan và rõ ràng hơn rất nhiều đối với các phương thức có tham số> 5 (quy tắc ngón tay cái của tôi).
STW

Đặc biệt hữu ích cho tự động hóa Office, nơi bạn phải đối phó với các phương pháp với hàng tá đối số tùy chọn.
MarkJ

1
Điều thú vị là bạn có thể kết hợp cả hai: bắt đầu bằng cách chỉ định các tham số bắt buộc theo thứ tự, sau đó chuyển sang các tham số được đặt tên cho các đối số tùy chọn!
RBarryYoung 19/09/09

15

Câu lệnh Sử dụng là mới kể từ VB 8, C # đã có nó ngay từ đầu. Nó gọi là xử lý tự động cho bạn.

Ví dụ

Using lockThis as New MyLocker(objToLock)

End Using

23
Cần lưu ý (chỉ vì tôi đã quên ít nhất hai lần) rằng bạn có thể có một câu lệnh Sử dụng bọc một số đối tượng Dùng một lần. Cú pháp là "Sử dụng objA làm đối tượng mới, objB làm đối tượng mới ...." Nó gọn gàng hơn nhiều so với lồng nhiều câu lệnh Sử dụng.
STW

Chắc chắn là một trong những mục yêu thích của tôi.
Sam Axe

14

Bí danh nhập khẩu cũng hầu như không được biết đến:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
Tôi nghĩ rằng chúng tôi đã có cùng một ý tưởng.
chrissie1 19/09/08

3
@Boo - đây là một ví dụ đơn giản mà bí danh nhập không phải là xấu. stackoverflow.com/questions/92869/…
torial

Được rồi - có một con đường rõ ràng cho sự lạm dụng, nhưng bất kể lời nói của @ torial thì đây là một tính năng tuyệt vời. Mỗi khi tôi bao gồm System.Text.RegularExpressions, tôi có nguy cơ xung đột tên với lớp "Nhóm" vì đó là tên lớp phổ biến. Bí danh cho phép bạn tránh phải đủ điều kiện các lớp mơ hồ, đây là một công cụ tiết kiệm thời gian rất lớn và thực sự nâng cao khả năng đọc khi được sử dụng đúng cách. Tính năng này rất tuyệt, nhưng ví dụ cụ thể của bạn thực sự đưa ra một số lời chế nhạo - xin lỗi phải nói.
mattmc3

14

Hãy xem xét khai báo sự kiện sau

Public Event SomethingHappened As EventHandler

Trong C #, bạn có thể kiểm tra người đăng ký sự kiện bằng cú pháp sau:

if(SomethingHappened != null)
{
  ...
}

Tuy nhiên, trình biên dịch VB.NET không hỗ trợ điều này. Nó thực sự tạo ra một trường thành viên riêng ẩn không hiển thị trong IntelliSense:

If Not SomethingHappenedEvent Is Nothing OrElse SomethingHappenedEvent.GetInvocationList.Length = 0 Then
...
End If

Thêm thông tin:

http://jelle.druyts.net/2003/05/09/BehindTheScenesOfEventsInVBNET.aspx http://blogs.msdn.com/vbteam/archive/2009/09/25/testing-events-for-nothing-null-doug -rothaus.aspx


Tại sao bạn lại muốn làm điều đó? Tôi không thể tưởng tượng một trường hợp sử dụng mà bạn cần biết số lượng người đăng ký một sự kiện trong VB.
Konrad Rudolph 19-08

Trong một số trường hợp nhất định, C # ném ra một ngoại lệ nếu bạn nâng cao sự kiện và không có trình xử lý nào. VB.Net sẽ không. Do đó cần phải kiểm tra.
Joel Coehoorn 19/09/08

2
Tôi đã sử dụng điều này cho một sự kiện đối tượng kinh doanh đưa ra thông báo lỗi xác thực cho người đăng ký. Tôi muốn kiểm tra xem sự kiện có đang được xử lý hay không để tôi biết lỗi xác thực đang được nhận. Nếu không, tôi đã đặt đối tượng kinh doanh một ngoại lệ.
Technobabble

2
Một cách sử dụng hữu ích khác cho thành viên riêng tư này là lấy danh sách yêu cầu của Sự kiện. Tôi đã sử dụng nó trong một số trường hợp để kích hoạt sự kiện theo cách không đồng bộ cho tất cả người gọi (ngăn Người nghe A sửa đổi sự kiện trước khi Người nghe B nhận được nó; cũng ngăn Người nghe A trì hoãn việc gửi đến Người nghe B). Tôi đã sử dụng điều này rất nhiều trong các kịch bản đồng bộ hóa dữ liệu tùy chỉnh và cả trong các API.
STW

14

Nếu bạn cần một tên biến để khớp với tên của từ khóa, hãy đặt nó trong dấu ngoặc. Không bị hoại tử. thực hành tốt nhất mặc dù - nhưng nó có thể được sử dụng một cách khôn ngoan.

ví dụ

Class CodeException
Public [Error] as String
''...
End Class

''later
Dim e as new CodeException
e.Error = "Invalid Syntax"

ví dụ: Ví dụ từ nhận xét (@Pondidum):

Class Timer
Public Sub Start()
''...
End Sub

Public Sub [Stop]()
''...
End Sub

Tôi nghĩ ví dụ này sẽ tốt hơn nếu bạn không sử dụng "Nếu" làm từ khóa ví dụ.
Sean Gough

4
timer.Start và timer.Stop mùa xuân với tâm trí như ví dụ về sử dụng tốt về điều này
Pondidum

5
+1 vì chỉ ra nó với tuyên bố từ chối trách nhiệm. Có một số lớp khung yêu cầu điều này phải giải quyết chính xác, chẳng hạn như [Assembly]
STW

5
[Enum] là một ví dụ điển hình khác về trường hợp bạn cần dấu ngoặc để sử dụng lớp thay vì từ khóa.
Ryan Lundy

13

Có một số câu trả lời về XML Literals, nhưng không phải về trường hợp cụ thể này:

Bạn có thể sử dụng XML Literals để bao gồm các ký tự chuỗi mà nếu không thì cần phải thoát. Ví dụ: chuỗi ký tự chứa dấu ngoặc kép.

Thay vì điều này:

Dim myString = _
    "This string contains ""quotes"" and they're ugly."

Bạn có thể làm được việc này:

Dim myString = _
    <string>This string contains "quotes" and they're nice.</string>.Value

Điều này đặc biệt hữu ích nếu bạn đang thử nghiệm một nghĩa đen để phân tích cú pháp CSV:

Dim csvTestYuck = _
    """Smith"", ""Bob"", ""123 Anywhere St"", ""Los Angeles"", ""CA"""

Dim csvTestMuchBetter = _
    <string>"Smith", "Bob", "123 Anywhere St", "Los Angeles", "CA"</string>.Value

( <string>Tất nhiên, bạn không phải sử dụng thẻ; bạn có thể sử dụng bất kỳ thẻ nào bạn thích.)


3
<q>sẽ là một thẻ tốt, tương tự như cách sử dụng trong Perl / Ruby. Dù sao, đó là một thành ngữ khá hay. GIỐNG!
Konrad Rudolph

Thật là một ý tưởng thiên tài. Cảm ơn bạn
Jeremy

12

DateTime có thể được khởi tạo bằng cách đặt ngày của bạn bằng #

Dim independanceDay As DateTime = #7/4/1776#

Bạn cũng có thể sử dụng kiểu suy luận cùng với cú pháp này

Dim independanceDay = #7/4/1776#

Điều đó đẹp hơn rất nhiều so với việc sử dụng hàm tạo

Dim independanceDay as DateTime = New DateTime(1776, 7, 4)

6
Không nếu bạn có Option Strict On
danlash

12

Bạn có thể có 2 dòng mã chỉ trong một dòng. vì thế:

Dim x As New Something : x.CallAMethod

whoa ... tôi nghĩ điều này chỉ có thể thực hiện được với lớp học và sự kế thừa
Jason

Đừng quênCall (New Something).CallAMethod()
Jonathan Allen

Đây là một phần mềm từ MS-Basic trên Apple] [! Trong cửa hàng của tôi, tôi cũng sẽ bị chế giễu vì sử dụng Gotos: - /
FastAl,

Hầu hết thời gian này là để tránh nhưng nơi tôi muốn sử dụng nó là trong trường hợp báo cáo nơi dòng này là thực sự ngắn ví dụ như Trường hợp 4: x = 22
dwidel

11

Các thông số tùy chọn

Các tùy chọn dễ dàng hơn nhiều so với việc tạo quá tải mới, chẳng hạn như:

Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
   Console.Writeline(msg)
   ''//do stuff
End Function

1
Tôi không biết rằng C # sẽ lấy được chúng. Họ là tốt đẹp, nhưng bạn phải cẩn thận để sử dụng chúng chỉ nơi bạn chắc chắn mã sẽ không được tiêu thụ bởi C # vì nó không hỗ trợ họ. FxCop / Phân tích mã sẽ cho bạn biết quá tải phương thức.
STW

... Tôi vừa tìm thấy một công dụng tuyệt vời cho các thông số Tùy chọn, trong khi vẫn giữ chúng không thuộc mã sản xuất. Tôi đã viết một bài đăng ngắn về nó trên trang web của mình: yoooder.com/wordpress/?p=62
STW

2
Ah, tôi khinh này rất nhiều ... Nhưng hữu ích cho Office tự động hóa
dance2die

9

Trường hợp tiêu đề trong VB.Net có thể đạt được bằng VB6 fxn cũ:

StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID

1
nó cũng trong lớp textinfo. không chắc chắn không gian tên nào nằm trong. có lẽ là system.text
Shawn

Bạn nên trung lập với ngôn ngữ .net và sử dụng lớp Globalization TextInfo để chuyển đổi ToTitleCase. Nếu bạn mã bao giờ cần phải được chuyển đổi sang C # bạn sẽ có rất nhiều hung hãn sống ít đòi hỏi Microsoft.VisualBasic
Jeremy

9

Thuộc tính có tham số

Tôi đã thực hiện một số lập trình C # và phát hiện ra một tính năng bị thiếu mà VB.Net có, nhưng không được đề cập ở đây.

Có thể xem ví dụ về cách thực hiện điều này (cũng như giới hạn của c #) tại: Sử dụng các thuộc tính get set điển hình trong C # ... với các tham số

Tôi đã trích đoạn mã từ câu trả lời đó:

Private Shared m_Dictionary As IDictionary(Of String, Object) = _
             New Dictionary(Of String, Object)

Public Shared Property DictionaryElement(ByVal Key As String) As Object
    Get
        If m_Dictionary.ContainsKey(Key) Then
            Return m_Dictionary(Key)
        Else
            Return [String].Empty
        End If
    End Get
    Set(ByVal value As Object)
        If m_Dictionary.ContainsKey(Key) Then
            m_Dictionary(Key) = value
        Else
            m_Dictionary.Add(Key, value)
        End If

    End Set
End Property

Điều này thật thú vị, nhưng tôi không hoàn toàn chắc chắn rằng điều này sẽ hữu ích ở đâu. myObj.Something ("abc") trông giống như bạn đang truy cập vào một Hàm hơn là một thuộc tính. Bạn không chắc điều này mua được gì.
mattmc3

Tôi ghét sự mơ hồ. Nó phải là gì. Một phương thức hoặc một thuộc tính. Một số công cụ refactoring khuyên bạn nên tạo cả trong những tình huống nhất định quá, trông giống như họ không hề biết ...
brumScouse
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.