คุณสมบัติที่ซ่อนอยู่ของ VB.NET?


121

ฉันได้เรียนรู้การเรียกดูผ่านคุณสมบัติที่ซ่อนอยู่ของ C # มาบ้างแล้วและรู้สึกประหลาดใจเมื่อไม่พบสิ่งที่คล้ายกันสำหรับ VB.NET

คุณลักษณะที่ซ่อนอยู่หรือที่รู้จักน้อยกว่าคืออะไร?

คำตอบ:


128

Exception Whenข้อไม่เป็นที่รู้จักส่วนใหญ่

พิจารณาสิ่งนี้:

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
มีประโยชน์ถ้าคุณต้องการจับ SQLException ที่เฉพาะเจาะจงพูดว่า -2 ซึ่งถ้าฉันจำได้ถูกต้องคือการหมดเวลาของเครือข่าย: Catch ex เป็น sqlException โดยที่ ex.code = -2
Pondidum

ว้าว! ฉันเพิ่งอ่านสิ่งนี้และนำไปใช้ทันทีเพื่อลดความซับซ้อนของบล็อก try / catch ที่เพิ่งเขียนเมื่อสัปดาห์ที่แล้ว ฉันไม่เคยมีสิ่งนี้มาก่อน
John M Gant

1
+1 และนี่คือส่วนที่บล็อกของทีม NET CLR อธิบายว่าเหตุใดตัวกรองข้อยกเว้นจึงมีประโยชน์blogs.msdn.com/clrteam/archive/2009/02/05/…
MarkJ

5
สิ่งนี้ไม่เพียงถูกซ่อนไว้ แต่ยังไม่มีใน C #
Cheeso

82

กำหนดเอง Enum s

หนึ่งในคุณสมบัติที่ซ่อนอยู่ของ VB คือcompletionlistแท็กเอกสาร XML ที่สามารถใช้ในการสร้างเองได้Enumชนิดที่เหมือนพร้อมฟังก์ชันเพิ่มเติม คุณลักษณะนี้ใช้ไม่ได้ใน C # แม้ว่า

ตัวอย่างหนึ่งจากรหัสล่าสุดของฉัน:

'
''' <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

ตอนนี้เมื่อกำหนดค่าให้กับตัวแปรประกาศเป็นRuleที่ IDE เสนอรายการ IntelliSense RuleTemplatesค่าที่เป็นไปได้จาก

/ แก้ไข:

เนื่องจากนี่เป็นคุณสมบัติที่อาศัย IDE จึงเป็นการยากที่จะแสดงให้เห็นว่าสิ่งนี้มีลักษณะอย่างไรเมื่อคุณใช้งาน แต่ฉันจะใช้ภาพหน้าจอ:

รายการดำเนินการเสร็จสิ้น http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

ในความเป็นจริง IntelliSense นั้นเหมือนกัน 100% กับสิ่งที่คุณได้รับเมื่อใช้Enumไฟล์.


น่าสนใจ - คุณสามารถแสดงตัวอย่างว่าสิ่งนี้มีลักษณะอย่างไรเมื่อคุณบริโภคมัน?
Brian MacKay

ดูเหมือนว่าใครบางคนยังสามารถสร้างกฎของตัวเองได้โดยเรียกตัวสร้างกฎโดยตรง? หากเป็นเช่นนั้นและหากคุณต้องการหยุดสิ่งนี้คุณสามารถประกาศผู้สร้างเป็น "เพื่อน" ในห้องสมุดของคุณได้ไหม
Joel Coehoorn

Joel ในโค้ดตัวอย่างของฉันฉันตั้งใจไม่ได้ห้ามสิ่งนี้ แต่ฉันเสนอกฎทั่วไปให้กับผู้ใช้และอนุญาตให้สร้างกฎเฉพาะของตัวเอง แน่นอนคุณสามารถป้องกันสิ่งนี้ได้โดยทำเครื่องหมายตัวสร้างเป็นfriendหรือโดยใช้คลาสเดียวกับ enum:RuleRuleTemplateแทน
Konrad Rudolph

มีรายการการใช้คุณลักษณะที่เป็นประโยชน์ซ่อนอยู่ที่ไหนบ้าง อันนี้ดูเหมือนเหลือเชื่อ แต่ฉันยังไม่แน่ใจว่าจะใช้มันที่ไหนหรือว่ามันสามารถแก้กริปหลักได้ในบางกรณีที่ไม่มีความสามารถในการ จำกัด การใช้งานทั่วไปสำหรับ enums
Maslow

@ Maslow: ไม่มีแอตทริบิวต์ที่เกี่ยวข้องที่นี่ นั่นคือความคิดเห็น xml
Joel Coehoorn

49

คุณสังเกตเห็นตัวดำเนินการเปรียบเทียบ Like หรือไม่?

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

เพิ่มเติมจาก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
รออะไร? นั่นเป็นเรื่องใหม่สำหรับฉัน! อืมนั่นดีกว่าทางเลือกอื่นด้วยการจัดการสตริง VB.NET: D
STW

.. !! ฉันไม่รู้ว่าแม้ว่าฉันจะทำงานในโครงการ vb.net หลายโครงการ! ฟีเจอร์ที่น่าสนใจ ...
Meta-Knight

woooooooooooooooooooooooow! ขอบคุณ! มันแย่มาก! มันทำงานใน ELinq, DLinq ด้วยหรือไม่? แล้ว XLinq ล่ะ?
Shimmy Weitzhandler

@dotjoe หืม? ไม่มีอะไร 'ขี้เกียจ' เกี่ยวกับ globs เหล่านี้
Josh Lee

สิ่งนี้ทำงานอย่างไรเกิดอะไรขึ้นภายใต้ประทุน? เป็นคำพ้องความหมายสำหรับไลบรารี reg ex หรือไม่?
brumScouse

48

typedefs

VB รู้จักประเภทดั้งเดิมtypedefผ่านImportนามแฝง:

Imports S = System.String

Dim x As S = "Hello"

สิ่งนี้มีประโยชน์มากกว่าเมื่อใช้ร่วมกับประเภททั่วไป:

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

2
โปรดแสดงตัวอย่างคำว่า Import ไม่เป็นที่รู้จักใน IDE ของฉัน
Shimmy Weitzhandler

5
Importsมันควรจะเป็น. ;-) อย่างไรก็ตามข้อผิดพลาดนี้ไม่ถูกตรวจพบ (และได้รับ 28 upvotes) เป็นเวลาเกือบทั้งปี
Konrad Rudolph

ฉันสงสัยเสมอว่าฉันจะสร้าง "ประเภท" ใหม่โดยมีค่าเริ่มต้นสำหรับสามัญได้อย่างไร! เย็น!
eidylon

3
นำเข้านำเข้า Importz อะไรก็ได้! Sheesh คุณคิดว่าเราอ่านโพสต์เหล่านี้ก่อนที่จะโหวตให้คะแนน!
MarkJ

สุดยอดสำหรับการใช้ xunit ในการทดสอบสตูดิโอภาพเช่นImports Assert = xUnit.Assert
wheelibin

45

Oh! และอย่าลืมXML Literalsตัวอักษร

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

นั่นคือสิ่งที่ฉันกำลังจะพูด อันที่จริงฉันใช้ตัวอักษร XML เพื่อจุดประสงค์ที่ไม่ได้ตั้งใจ ฉันใช้มันเพื่อผลิต Javascript ... swortham.blogspot.com/2009/03/vb-2008.html
Steve Wortham

9
เหนือสิ่งอื่นใดคุณสามารถใช้ XML Literals เพื่อหลีกเลี่ยงการหลบหนีของสตริงที่น่าเกลียดเช่นเมื่อคุณใช้สตริงที่มีเครื่องหมายอัญประกาศคู่ เพียงใส่สตริงไว้ใน XML Literal แล้วเรียก Value ดังนี้: <string>This string contains "quotes" and it's OK.</string>.Value (ฉันพบว่าสิ่งนี้มีประโยชน์อย่างยิ่งเมื่อเขียนการทดสอบเกี่ยวกับการแยกวิเคราะห์ไฟล์ CSV ที่ทุกฟิลด์อยู่ในเครื่องหมายคำพูดมันคงไม่ใช่เรื่องสนุกที่จะหลีกหนีคำพูดเหล่านั้นทั้งหมดด้วยมือของฉัน แนวข้อสอบ)
Ryan Lundy

2
@Kyralessa: +1 ความคิดเห็นที่ยอดเยี่ยม ในความเป็นจริงมันเป็นวิธีที่ดีในการระบุสตริงหลายบรรทัด (กอดคำสั่ง SQL ฯลฯ )
Heinzi

Inline XML เป็นหนึ่งในคุณสมบัติ VB.NET ที่แย่ที่สุดที่เคยมีมา ข้อเท็จจริงที่ไม่ชัดเจน
Grant Thomas

39

การเริ่มต้นวัตถุอยู่ในนั้นด้วย!

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

1
ไม่อยากจะเชื่อเลยว่าพวกเขาใช้เหล็กดัดฟัน เรามีคำสั่ง With อยู่แล้ว .. พวกเขาสามารถใช้ไวยากรณ์นั้นซ้ำได้
Sam Axe

2
ฉันรู้ว่ามันสร้างขึ้นเพื่อแสดงให้คุณเห็นว่าไม่มีตำรวจอยู่บนท้องถนน ... lol JK
Shimmy Weitzhandler

4
จะเกิดอะไรขึ้นเมื่อนักเขียนคอมไพเลอร์ทุกคนต่างก็เป็นนักเขียนโปรแกรม C / C ++ ที่เป็นหัวใจของตัวเอง พวกเขาเลื่อนไวยากรณ์ C ไปเป็นภาษาอื่น ๆ อยู่เรื่อย ๆ เพราะพวกเขาไม่สามารถคิดได้ว่าอะไรจะดีไปกว่านี้
RBarryYoung

38

DirectCast

DirectCastเป็นเรื่องมหัศจรรย์ บนพื้นผิวมันทำงานคล้ายกับตัวCTypeดำเนินการที่จะแปลงวัตถุจากประเภทหนึ่งไปเป็นอีกประเภทหนึ่ง อย่างไรก็ตามมันทำงานโดยใช้กฎที่เข้มงวดกว่ามาก CTypeพฤติกรรมที่แท้จริงของดังนั้นจึงมักจะทึบแสงและไม่ชัดเจนเลยว่าการแปลงประเภทใดถูกดำเนินการ

DirectCast รองรับการดำเนินการสองอย่างเท่านั้น:

  • Unboxing ประเภทค่าและ
  • การอัปเดตในลำดับชั้นของคลาส

การแคสต์อื่น ๆ จะไม่ทำงาน (เช่นการพยายาม unbox an Integerto a Double) และจะส่งผลให้เกิดข้อผิดพลาดเวลาคอมไพล์ / รันไทม์ (ขึ้นอยู่กับสถานการณ์และสิ่งที่ตรวจพบได้โดยการตรวจสอบประเภทคงที่) ฉันจึงใช้DirectCastทุกครั้งที่เป็นไปได้เนื่องจากสิ่งนี้จับจุดประสงค์ของฉันได้ดีที่สุด: ขึ้นอยู่กับสถานการณ์ฉันต้องการแกะกล่องค่าของประเภทที่รู้จักหรือทำการอัปแคสต์ ตอนจบของเรื่อง.

การใช้ CTypeบนมืออื่น ๆ ที่ออกจากผู้อ่านของรหัสสงสัยว่าสิ่งที่โปรแกรมเมอร์ตั้งใจจริงๆเพราะมันหายไปทุกชนิดของการดำเนินงานที่แตกต่างกันรวมทั้งการเรียกรหัสผู้ใช้กำหนด

เหตุใดจึงเป็นคุณลักษณะที่ซ่อนอยู่ ทีมงาน VB ได้เผยแพร่แนวทางที่1ที่ไม่สนับสนุนการใช้งานDirectCast(แม้ว่าจะเร็วกว่าก็จริง!) เพื่อให้โค้ดมีความสม่ำเสมอมากขึ้น ฉันยืนยันว่านี่เป็นแนวทางที่ไม่ดีที่ควรย้อนกลับ: เมื่อใดก็ตามที่เป็นไปได้ให้DirectCastเลือกCTypeผู้ปฏิบัติงานทั่วไปมากกว่า ทำให้โค้ดชัดเจนขึ้นมาก CTypeในทางกลับกันควรเรียกก็ต่อเมื่อสิ่งนี้มีจุดมุ่งหมายจริง ๆ เท่านั้นเช่นเมื่อควรเรียกตัวCTypeดำเนินการจำกัด(เทียบกับตัวดำเนินการมากเกินไป )


1)ฉันไม่สามารถหาลิงค์ไปยังแนวทางได้ แต่ฉันพบว่าPaul Vick รับไปแล้ว (หัวหน้าผู้พัฒนาของทีม VB):

ในโลกแห่งความเป็นจริงคุณแทบจะไม่สังเกตเห็นความแตกต่างดังนั้นคุณอาจใช้ตัวดำเนินการแปลงที่ยืดหยุ่นกว่าเช่น CType, CInt และอื่น ๆ


(แก้ไขโดย Zack: เรียนรู้เพิ่มเติมที่นี่: ฉันจะแคสต์ใน VB.NET ได้อย่างไร )


จริงๆแล้วฉันชอบ TryCast () ดีกว่าเล็กน้อย จะไม่ทำให้เกิดข้อยกเว้นเพียงแค่ส่งคืน Nothing หากการร่ายล้มเหลว หากคุณคาดว่าการแคสต์จะล้มเหลวบ่อยครั้งจะเร็วกว่า If TypeOf x Is T ... DirectCast (x, T) และเร็วกว่าการจับข้อยกเว้นหาก DirectCast ล้มเหลว
Bob King

6
DirectCast () และ TryCast () มีค่ามากเมื่อใช้เป็นคู่อย่างถูกต้อง DirectCast () ควรจะใช้ในกรณีที่โยนวัตถุมีความเป็นอยู่เสมอคาดว่าจะเป็นประเภทเป้าหมาย (ถ้ามันไม่ได้คุณจะได้รับข้อผิดพลาดเป็นสิ่งที่ดีเพราะมันเป็นสถานการณ์ที่ไม่คาดคิด) ควรใช้ TryCast () หากวัตถุที่กำลังร่ายอาจเป็นประเภทเป้าหมายหรือประเภทเป้าหมายหลายประเภท การใช้อย่างใดอย่างหนึ่งโดยเฉพาะจะนำไปสู่ค่าโสหุ้ยพิเศษ (ถ้า typeof x เป็น y แสดงว่า directcast (x, y) ไม่มีประสิทธิภาพ) หรือเพื่อหลีกเลี่ยงข้อผิดพลาดที่ถูกต้อง (โดยใช้ TryCast () สำหรับกรณีที่วัตถุควรเป็นประเภทเป้าหมายเสมอ )
STW

Yoooder: ถูกต้อง 100% มันเป็นความอัปยศผมไม่ได้พูดถึงการกลับมาแล้วตั้งแต่ผมส่วนใหญ่มีกระดูกเพื่อรับกับการใช้งานที่แพร่หลายของTryCast CType
Konrad Rudolph

@ Maslow: แน่นอนว่าไม่เป็นเช่นนั้นเนื่องจาก Enums เป็นประเภทค่าและTryCastใช้ได้เฉพาะกับประเภทการอ้างอิงเท่านั้นตามเอกสารประกอบ
Konrad Rudolph

+1: เฮ้ ฉันต้องยอมรับว่าฉันอ่านแค่นี้และคิดว่า "โอ้ใช่ DirectCast ฉันลืมเรื่องนั้นได้อย่างไร" จากนั้นฉันก็ใช้มันกับโค้ดบรรทัดถัดไปของฉัน (เนื่องจากฉันไม่ชอบ CType จริงๆ)
RBarryYoung

37

If ตัวดำเนินการตามเงื่อนไขและรวมตัวกัน

ฉันไม่รู้ว่าคุณจะเรียกมันว่าซ่อนอย่างไร แต่ Iif ([expression], [value if true], [value if false]) เนื่องจากฟังก์ชัน Object สามารถนับได้

มันไม่ได้ถูกซ่อนไว้มากเท่าที่เลิกใช้งาน ! VB 9 มีตัวIfดำเนินการที่ดีกว่ามากและทำงานได้เหมือนกับตัวดำเนินการตามเงื่อนไขและตัวรวมกันของ C # (ขึ้นอยู่กับสิ่งที่คุณต้องการ):

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

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

แก้ไขเพื่อแสดงตัวอย่างอื่น:

สิ่งนี้จะใช้ได้If()แต่ทำให้เกิดข้อยกเว้นด้วยIIf()

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

ดีฉันไม่รู้! ฉันเพิ่งใช้ IIF เมื่อวานนี้ดังนั้นฉันจะกลับไปที่บล็อกรหัสนั้นอีกครั้ง
Sean Gough

4
บอก VS 2005 ว่า ไม่ใช่ทุกคนที่จะได้ร่วมงานกับสิ่งใหม่ล่าสุดและยิ่งใหญ่ที่สุด
Sam Erwin

3
@ หยาบไร้สาระ. วิธีนี้ปลอดภัย 100% และส่งคืนอ็อบเจ็กต์ประเภทเดียวกับอาร์กิวเมนต์ (ที่สองและสาม) นอกจากนี้ต้องมีการแปลงที่กว้างขึ้นระหว่างอาร์กิวเมนต์มิฉะนั้นจะมีข้อผิดพลาดในการคอมไพล์เนื่องจากประเภทไม่ตรงกัน
Konrad Rudolph

1
ใช่ IIf () ที่ไม่ปลอดภัย
Pondidum

2
@ Br.Bill อันที่จริงมันเทียบเท่ากับ:?ตัวดำเนินการของ C และ Perl อย่างสมบูรณ์ไม่ใช่แค่เวอร์ชันที่เรียบง่าย
Konrad Rudolph

32

นี่เป็นสิ่งที่ดี คำสั่ง Select Case ภายใน VB.Net มีประสิทธิภาพมาก

แน่นอนว่ามีมาตรฐาน

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

แต่มีมากกว่านั้น ...

คุณสามารถทำช่วง:

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

และมากยิ่งขึ้น ...

คุณสามารถ (แม้ว่าอาจไม่ใช่ความคิดที่ดี) ทำการตรวจสอบบูลีนกับตัวแปรหลายตัว:

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
จริงๆแล้วคุณพลาดไปสองสามข้อ: ก) การใช้ "Select Case True" เพื่อทดสอบตัวแปรมากกว่าหนึ่งตัว b) การใช้แบบฟอร์ม "Case A, B, ... " และแม้แต่ c) การใช้ ":" กับ in- บรรทัดคำสั่งการดำเนินการกับเงื่อนไขเงื่อนไข (แม้ว่าหลายคนไม่ชอบสิ่งนี้)
RBarryYoung

6
โปรดอย่าใช้ Select Case True เพียงใช้คำสั่ง If
Ryan Lundy

4
ฉันพบว่า Select Case True อ่านง่ายกว่าคำสั่ง ifelse ขนาดใหญ่มาก
งด

ปัญหาเกี่ยวกับการSelect Case Trueเป็นว่ามันดูราวกับว่ามันประเมินแต่ละของCaseงบและทำงานรหัสสำหรับแต่ละคนที่เป็นจริง แต่ในความเป็นจริงมันประเมินพวกเขาทีละคนและรันโค้ดสำหรับโค้ดแรกที่เป็นจริงเท่านั้น ไวยากรณ์สำหรับIfมีความชัดเจนมากขึ้นในเรื่องนี้ ( If...Else If...Else If...Else)
Ryan Lundy

31

โปรแกรมประหยัดเวลาที่สำคัญอย่างหนึ่งที่ฉันใช้ตลอดเวลาคือคำหลักด้วย :

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

ฉันไม่ชอบพิมพ์มากกว่าที่ฉันต้องทำ!


แต่มันยังสร้างจุดบกพร่องบางอย่างที่ซ่อนอยู่โดยเฉพาะเมื่อคุณมี With within With
Varun Mahajan

2
ฉันไม่รู้ด้วยซ้ำว่าคุณสามารถใส่ With ใหม่ภายใน With ที่มีอยู่ได้ แค่เลอะเทอะ!
Bob King

2Bob: มันไม่ได้เลอะเทอะผมขอแนะนำ .. มันเป็นเพียงการสร้างภาษาที่จะใช้ด้วยความระมัดระวัง สำหรับการตั้งค่าคุณสมบัติจำนวนมากในบรรทัดต่อ ๆ กันมันยอดเยี่ยมมาก แต่การค้นหาแบบสุ่ม Fu ในโค้ดที่ซับซ้อนแล้วต้องตามล่าด้วยคำสั่ง x บรรทัดด้านบนไม่ใช่การใช้คุณสมบัติที่ดี
ChrisA

2
Wish C # มีสิ่งนี้ไหม หรือว่าฉันหลับไปแล้วและอยู่ในคำตอบ C # hidden-features แล้ว ... ? ;-)
peSHIr

1
@ บู: คุณพูดถูก แต่ก็ยังรำคาญที่คุณไม่สามารถเพิ่มลงในรายการเฝ้าดูได้
Meta-Knight

31

ตัวแยกวิเคราะห์ CSV ที่ดีที่สุดและใช้งานง่าย:

Microsoft.VisualBasic.FileIO.TextFieldParser

ด้วยการเพิ่มการอ้างอิงไปยัง Microsoft.VisualBasic สิ่งนี้สามารถใช้ในภาษา. Net อื่น ๆ เช่น C #


5
+1 เป็นเรื่องแปลกที่คน C # วิ่งไปที่ FileHelpers โดยไม่ได้คำนึงถึงสิ่งนี้เลย ฉันแน่ใจว่า FileHelpers นั้นยอดเยี่ยม แต่เป็นการพึ่งพาภายนอก
MarkJ

@MarkJ ฉันคิดว่ามันเป็นเพราะความไม่รู้
Nathan Koop

ฉันออกจากนรกจากการพยายามค้นหาชั้นเรียนนี้และไม่เคยทำเลยขอบคุณที่แสดงความคิดเห็น!
ปิงปอง

26
  • AndAlso / OrElse ตัวดำเนินการเชิงตรรกะ

(แก้ไข: เรียนรู้เพิ่มเติมที่นี่: ฉันควรใช้ตัวดำเนินการ AndAlso และ OrElse หรือไม่ )


ฉันจะไม่เรียกมันว่าซ่อนเลยถ้าผู้ติดต่อไม่มีอะไรและยังติดต่อด้วย ContactId> 0 แล้วทำมันถ้าคุณจะใช้และคุณจะมีข้อยกเว้นโยน
Shimmy Weitzhandler

25

สมาชิกคงในวิธีการ.

ตัวอย่างเช่น:

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

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

ในฟังก์ชันด้านบนนิพจน์ทั่วไปของรูปแบบจะถูกสร้างขึ้นเพียงครั้งเดียวไม่ว่าฟังก์ชันจะถูกเรียกใช้กี่ครั้งก็ตาม

การใช้งานอีกอย่างหนึ่งคือการเก็บตัวอย่าง "สุ่ม" ไว้รอบ ๆ :

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

    Return r.Next()
End Function 

นอกจากนี้ยังไม่เหมือนกับการประกาศว่าเป็นสมาชิกที่ใช้ร่วมกันของชั้นเรียน รายการที่ประกาศด้วยวิธีนี้รับประกันว่าปลอดภัยต่อเกลียวเช่นกัน มันไม่สำคัญในสถานการณ์นี้เนื่องจากนิพจน์จะไม่มีวันเปลี่ยนแปลง แต่มีบางอย่างที่อาจเกิดขึ้นได้


1
การใช้วิธีนี้อย่างหนึ่งคือการรักษาตัวนับที่จะเพิ่มขึ้นทุกครั้งที่มีการเรียกใช้เมธอด หากตัวแปรถูกทำเครื่องหมายว่าคงที่ตัวแปรนั้นจะไม่ถูกกำหนดค่าเริ่มต้นใหม่ในการเรียกแต่ละวิธี จะเริ่มต้นในการโทรครั้งแรกเท่านั้นและหลังจากนั้นจะคงค่าไว้
Ryan Lundy

นี่คือเหตุผลว่าทำไมสมาชิกชั้นเรียนคงตั้งชื่อ "shared" ใน VB.NET
Enrico Campidoglio

Static เป็นรูปแบบที่ไม่ดีใน VB.NET มากกว่าที่เป็นใน VB แบบคลาสสิก ควรหลีกเลี่ยงตัวแปรคงที่ทุกครั้งที่ทำได้
Sam Axe

6
@ บู - สวยกวาดเลย เหตุผลของคุณคืออะไร? ฉันคิดว่าตัวแปรคงมีประโยชน์
MarkJ

4
คงที่ซึ่งใช้ในตัวอย่างข้างต้นอนุญาตให้มีรูปแบบเฉพาะของการห่อหุ้ม: ตัวแปรระดับชั้นที่มีขอบเขตระดับวิธีการ หากไม่มีคุณจะต้องสร้างตัวแปรระดับชั้นที่สมาชิกชั้นเรียนทุกคนสามารถเข้าถึงได้แม้ว่าคุณจะใช้เพียงวิธีเดียวก็ตาม
Ryan Lundy

25

ใน vb มีความแตกต่างระหว่างตัวดำเนินการเหล่านี้:

/จะDouble
\ถูกIntegerละเลยส่วนที่เหลือ

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
ฉันได้เรียนรู้สิ่งนี้เป็นวิธีที่ยากเมื่อพยายามค้นหาเข็มในรหัสล้านบรรทัด การหารปกติเทียบกับจำนวนเต็ม เคล็ดลับดีๆ!
Jason Irwin

23

ฉันชอบเนมสเปซ "ของฉัน"ซึ่งเปิดตัวใน Visual Basic 2005 มากฉันเป็นทางลัดไปยังกลุ่มข้อมูลและฟังก์ชันต่างๆ ให้การเข้าถึงข้อมูลประเภทต่อไปนี้อย่างรวดเร็วและใช้งานง่าย:

  • My.Computer : การเข้าถึงข้อมูลที่เกี่ยวข้องกับคอมพิวเตอร์เช่นระบบไฟล์เครือข่ายอุปกรณ์ข้อมูลระบบ ฯลฯ ซึ่งให้การเข้าถึงทรัพยากรที่สำคัญจำนวนมากรวมถึง My.Computer.Network, My.Computer.FileSystem และ My .Computer.Printers
  • แอปพลิเคชันของฉัน : เข้าถึงข้อมูลที่เกี่ยวข้องกับแอปพลิเคชันเฉพาะเช่นชื่อเวอร์ชันไดเร็กทอรีปัจจุบันเป็นต้น
  • My.User : เข้าถึงข้อมูลที่เกี่ยวข้องกับผู้ใช้ที่ได้รับการพิสูจน์ตัวตนในปัจจุบัน
  • My.Resources : เข้าถึงทรัพยากรที่แอปพลิเคชันใช้อยู่ในไฟล์ทรัพยากรในลักษณะที่พิมพ์ผิด
  • My.Settings : เข้าถึงการตั้งค่าการกำหนดค่าของแอปพลิเคชันในลักษณะที่พิมพ์ผิด

นี่เป็นสิ่งที่ยอดเยี่ยมและผู้ชาย vb.net ทุกคนควรรู้สิ่งต่างๆในเนมสเปซของฉันมันมีประโยชน์มาก
ดร. ชั่วร้าย

ของฉัน * FTW :)
ดร. ชั่วร้าย

3
มันมีประโยชน์ แต่ฉันเกลียดชื่อที่โง่ลง ทำให้ฉันนึกถึงsecretgeek.net/refactvb.asp
MarkJ

23

เหตุการณ์ที่กำหนดเอง

แม้ว่าจะไม่ค่อยมีประโยชน์ แต่การจัดการเหตุการณ์สามารถปรับแต่งได้มาก:

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

จากนั้นสามารถทดสอบได้ในลักษณะต่อไปนี้:

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

ดูดี แต่ถ้าฉันต้องการสิ่งนี้ฉันคิดว่าฉันคงทำอะไรผิดพลาด ;-) ดูเหมือนว่าจะผิดหลักการ KISS
chrissie1

4
มันมีประโยชน์มากจริงๆเมื่อคุณต้องการให้แน่ใจว่าอ่างล้างจานทุกชิ้นได้รับเหตุการณ์แม้ว่าจะมีข้อยกเว้นอย่างน้อยหนึ่งรายการก็ตาม
Jonathan Allen

ค่าอื่น (ฉันเพิ่งอ่านบนไซต์ MSDN) คือถ้าชั้นเรียนของคุณพ่นเหตุการณ์จำนวนมากคุณสามารถบังคับให้ใช้ตารางแฮช / พจนานุกรมเป็นคอนเทนเนอร์แทนการประกาศฟิลด์สำหรับแต่ละเหตุการณ์ msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
torial

เย็น. ฉันคิดว่านี่เป็นหนึ่งในคุณสมบัติที่แยก C # และ VB.NET ออกจากกัน (เช่นเดียวกับที่ทำได้ แต่อีกคุณสมบัติหนึ่งไม่มีไวยากรณ์สำหรับมัน) ยินดีที่ได้รู้ว่าฉันคิดผิดในแง่นี้
peSHIr

21

ฉันเพิ่งพบบทความที่พูดถึง "!" โอเปอเรเตอร์หรือที่เรียกว่า "ตัวดำเนินการค้นหาพจนานุกรม" นี่คือข้อความที่ตัดตอนมาจากบทความที่: http://panopticoncentral.net/articles/902.aspx

ชื่อทางเทคนิคสำหรับ! โอเปอเรเตอร์คือ "ตัวดำเนินการค้นหาพจนานุกรม" พจนานุกรมคือประเภทคอลเลกชันใด ๆ ที่จัดทำดัชนีด้วยคีย์แทนที่จะเป็นตัวเลขเช่นเดียวกับวิธีการจัดทำดัชนีรายการในพจนานุกรมภาษาอังกฤษโดยคำที่คุณต้องการให้นิยาม ตัวอย่างที่พบบ่อยที่สุดของประเภทพจนานุกรมคือ System.Collections.Hashtable ซึ่งช่วยให้คุณสามารถเพิ่มคู่ (คีย์ค่า) ลงในแฮชแท็กจากนั้นดึงค่าโดยใช้คีย์ ตัวอย่างเช่นรหัสต่อไปนี้จะเพิ่มรายการลงในแฮชแท็กสามรายการและค้นหาหนึ่งในนั้นโดยใช้คีย์ "หมู"

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

เดอะ! สามารถใช้ตัวดำเนินการเพื่อค้นหาค่าจากพจนานุกรมประเภทใดก็ได้ที่ทำดัชนีค่าโดยใช้สตริง ตัวระบุหลัง! ใช้เป็นกุญแจสำคัญในการดำเนินการค้นหา ดังนั้นจึงสามารถเขียนโค้ดด้านบนแทนได้:

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

ตัวอย่างที่สองนั้นเทียบเท่ากับตัวอย่างแรก แต่ก็ดูดีกว่ามากอย่างน้อยก็ในสายตาของฉัน ฉันพบว่ามีหลายแห่งที่! สามารถใช้งานได้โดยเฉพาะอย่างยิ่งเมื่อพูดถึง XML และเว็บซึ่งมีคอลเล็กชันมากมายที่จัดทำดัชนีด้วยสตริง ข้อ จำกัด ที่น่าเสียดายอย่างหนึ่งคือสิ่งที่ตามมา! ยังคงต้องเป็นตัวระบุที่ถูกต้องดังนั้นหากสตริงที่คุณต้องการใช้เป็นคีย์มีอักขระตัวระบุที่ไม่ถูกต้องอยู่คุณจะไม่สามารถใช้! ผู้ประกอบการ (ตัวอย่างเช่นคุณไม่สามารถพูดว่า "Table! AB $ CD = 5" เนื่องจาก $ ไม่ถูกกฎหมายในตัวระบุ) ใน VB6 และก่อนหน้านี้คุณสามารถใช้วงเล็บเพื่อหลีกเลี่ยงตัวระบุที่ไม่ถูกต้อง (เช่น "Table! [AB $ CD] ") แต่เมื่อเราเริ่มใช้วงเล็บเพื่อหลีกเลี่ยงคำหลักเราสูญเสียความสามารถในการทำเช่นนั้น ในกรณีส่วนใหญ่,

เพื่อให้ได้เทคนิคจริงๆ x! y จะทำงานถ้า x มีคุณสมบัติเริ่มต้นที่รับ String หรือ Object เป็นพารามิเตอร์ ในกรณีนั้น x! y จะเปลี่ยนเป็น x.DefaultProperty ("y") ข้อสังเกตที่น่าสนใจคือมีกฎพิเศษในไวยากรณ์ศัพท์ของภาษาเพื่อให้ทุกอย่างทำงานได้ เดอะ! อักขระยังใช้เป็นอักขระประเภทในภาษาและอักขระประเภทจะถูกกินก่อนตัวดำเนินการ ดังนั้นหากไม่มีกฎพิเศษ x! y จะถูกสแกนเป็น "x! y" แทน "x! y" โชคดีที่ไม่มีที่ใดในภาษาที่ตัวระบุสองตัวในแถวถูกต้องเราจึงแนะนำกฎว่าถ้าอักขระตัวถัดไปหลังจาก! เป็นจุดเริ่มต้นของตัวระบุเราพิจารณา! เป็นตัวดำเนินการไม่ใช่อักขระประเภท


11
นั่นเป็นหนึ่งในคุณสมบัติที่ฉันใช้แล้วโดยเจตนาลืมไป ช่วยประหยัดการกดแป้นพิมพ์ไม่กี่ครั้ง แต่ทำให้โค้ดของฉันไฮไลต์และอ่านง่ายขึ้น ลืมอีกแล้วใช่ไหม .... NOW
STW

3
น่าสนใจ แต่ไม่มีประโยชน์จริงๆ นี่เป็นสิ่งที่ทีม VB ทำงานแทนการเพิ่มคุณสมบัติที่ขาดหายไปเช่นคีย์เวิร์ดผลตอบแทนหรือไม่? : P
Meta-Knight

5
คุณลักษณะนี้มีไว้เพื่อความเข้ากันได้แบบย้อนหลังจาก VB3 (AFAIK)
Eduardo Molteni

1
คลาสที่ใช้ดัชนีคีย์มีอินเทอร์เฟซทั่วไปที่สืบทอดมาหรือไม่ เช่น IKeyed วิธีเดียวกับคอนเทนเนอร์ที่ทำดัชนีจำนวนเต็มใช้ IENumberable หรือไม่
Maslow

2
คุณลักษณะนี้ยังทำงานร่วมกับ DataRows (เช่น dr! ID) ซึ่งมีประโยชน์มากใน LINQ ไปยังชุดข้อมูล
พอล

19

สิ่งนี้มีอยู่ในตัวและมีข้อได้เปรียบเหนือ C # ความสามารถในการใช้วิธีการเชื่อมต่อโดยไม่ต้องใช้ชื่อเดียวกัน

เช่น:

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

End Sub

ฉันมั่นใจว่าคุณสามารถทำสิ่งนี้ใน C # ได้ ใน VB.NET มันบังคับและใน C # เป็นทางเลือก?
Jesper Blad Jensen

5
คุณยังสามารถทำให้ sub เป็นส่วนตัวได้ซึ่งเป็นวิธีที่ยอดเยี่ยมในการซ่อนสิ่งต่างๆเช่นการเรียกใช้อินเทอร์เฟซเวอร์ชันที่ไม่ใช่แบบทั่วไปที่เลิกใช้งาน
Craig Gidney

3
อาจเป็นความคิดที่ดี ตัวอย่างคลาสสิกคือถ้าคุณต้องการวิธีการปิดสาธารณะที่ทำหน้าที่เป็นการนำไปใช้งาน Dispose สำหรับ IDisposable
MarkJ

1
นอกจากนี้ยังมีประโยชน์มากหากคุณใช้สองอินเทอร์เฟซที่ใช้ชื่อเมธอดร่วมกัน
Eric Nicholson

ฉันได้เห็นสิ่งนี้และหวังว่าฉันจะไม่มี ไม่ควรได้รับอนุญาต.
FastAl

17

บังคับ ByVal

ใน VB ถ้าคุณรวมอาร์กิวเมนต์ของคุณไว้ในวงเล็บพิเศษคุณสามารถแทนที่การประกาศ ByRef ของวิธีการและเปลี่ยนเป็น ByVal ตัวอย่างเช่นรหัสต่อไปนี้จะสร้าง 4, 5, 5 แทนที่จะเป็น 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

โปรดดูอาร์กิวเมนต์ที่ไม่ได้ถูกแก้ไขโดยการเรียกโพรซีเดอร์ - ตัวแปรที่อยู่ภายใต้


6
โอ้ความดีของฉัน ... นั่นเป็นคุณสมบัติที่โดดเด่นแม้ว่าฉันไม่คิดว่าฉันจะรู้ว่ามันกำลังทำอะไรถ้าฉันอ่านมันในรหัสของคนอื่น หากคุณต้องแสดงความคิดเห็นเพื่อให้ทราบว่ากำลังทำอะไรอยู่คุณอาจทำให้ตัวแปรการทิ้งเพื่อส่งผ่านแทน
mattmc3

7
นี่เป็นผลข้างเคียงของการใช้วงเล็บ - วงเล็บสร้างค่าชั่วคราวของสิ่งที่อยู่ภายในแม้ว่าจะมีเพียงรายการเดียวก็ตาม เอฟเฟกต์นี้ฆ่าฉันใน vb6 - การโทรย่อยไม่ได้ใช้ parens แต่ฉันมาจาก C โดยสัญชาตญาณทำให้ parens เข้ามา 6.0 ทำให้เกิดพารามิเตอร์หลายตัว แต่สำหรับพารามิเตอร์ย่อยหนึ่งพารามิเตอร์นั้นส่งผ่านค่า temp อย่างมีความสุขและถูกแทนที่เพื่อให้เกียรติของฉัน 'ByRef' เกิดขึ้นทุกๆ 3 ปีซึ่งเป็นช่วงเวลาที่ทำให้ฉันลืมเหตุการณ์สุดท้ายได้
FastAl

16

ส่งผ่านพารามิเตอร์ตามชื่อและเรียงลำดับใหม่

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

    'Do stuff

End function

การใช้งาน:

Module Module1

    Sub Main()

        MyFunc() 'No params specified

    End Sub

End Module

ยังสามารถเรียกโดยใช้ข้อกำหนดพารามิเตอร์ ": =" ในลำดับใดก็ได้:

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

ว้าวสุดยอดมาก! ฉันเห็นสิ่งนี้เมื่อใช้บริการเว็บ ฯลฯ แต่ฉันไม่รู้ว่าคุณสามารถทำวิธีนี้ได้ทุกวิธีปกติ
RichC

2
เป็นเครื่องมือที่มีประโยชน์อย่างแน่นอนเมื่อคุณพบวิธีที่ใช้ข้อโต้แย้งมากเกินไป ฉันพยายามตั้งชื่อพารามิเตอร์แต่ละตัวและใส่ชื่อ: = ค่าในบรรทัดของมันเอง มันใช้งานง่ายและสะอาดกว่ามากสำหรับวิธีการที่ใช้พารามิเตอร์> 5 (กฎง่ายๆของฉัน)
STW

มีประโยชน์อย่างยิ่งสำหรับ Office Automation ซึ่งคุณต้องรับมือกับวิธีการที่มีอาร์กิวเมนต์ที่เป็นทางเลือกมากมาย
MarkJ

1
สิ่งที่เจ๋งก็คือคุณสามารถผสมทั้งสองอย่างได้: เริ่มต้นด้วยการระบุพารามิเตอร์ที่ต้องการตามลำดับจากนั้นเปลี่ยนเป็นพารามิเตอร์ที่มีชื่อสำหรับอาร์กิวเมนต์ที่เป็นทางเลือก!
RBarryYoung

15

คำสั่งการใช้เป็นคำสั่งใหม่เมื่อเทียบกับ VB 8, C # มีตั้งแต่เริ่มต้น มันเรียกการกำจัดโดยอัตโนมัติสำหรับคุณ

เช่น

Using lockThis as New MyLocker(objToLock)

End Using

23
เป็นที่น่าสังเกต (เพียงเพราะฉันลืมอย่างน้อยสองครั้ง) ว่าคุณสามารถมีคำสั่งการใช้คำสั่งห่อหลายวัตถุทิ้งได้ ไวยากรณ์คือ "Using objA as new object, objB as new object .... " มันสะอาดกว่าการซ้อนคำสั่งหลาย ๆ คำสั่งโดยใช้
STW

เป็นหนึ่งในรายการโปรดของฉันเช่นกัน
Sam Axe

14

ชื่อแทนการนำเข้ายังไม่ทราบส่วนใหญ่:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
ฉันคิดว่าเรามีความคิดเดียวกัน
chrissie1

3
@ บู - นี่คือตัวอย่างง่ายๆที่นามแฝงนำเข้าไม่ใช่สิ่งชั่วร้าย stackoverflow.com/questions/92869/...
torial

โอเค - มีช่องทางที่ชัดเจนสำหรับการละเมิด แต่ไม่ว่า @ torial จะพูดจาโผงผางก็ตามนี่เป็นคุณสมบัติที่ยอดเยี่ยม ทุกครั้งที่ฉันใส่ System.Text.RegularExpressions ฉันเสี่ยงที่ชื่อจะชนกับคลาส "Group" เนื่องจากเป็นชื่อคลาสทั่วไป นามแฝงช่วยให้คุณหลีกเลี่ยงการต้องผ่านคุณสมบัติของคลาสที่ไม่ชัดเจนซึ่งช่วยประหยัดเวลาได้มากและช่วยเพิ่มความสามารถในการอ่านเมื่อใช้อย่างถูกต้อง คุณลักษณะนี้ยอดเยี่ยม แต่ตัวอย่างเฉพาะของคุณเชิญชวนให้มีการเยาะเย้ย - ขอโทษที่ต้องพูด
mattmc3

14

พิจารณาการประกาศเหตุการณ์ต่อไปนี้

Public Event SomethingHappened As EventHandler

ใน C # คุณสามารถตรวจสอบสมาชิกเหตุการณ์โดยใช้ไวยากรณ์ต่อไปนี้:

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

อย่างไรก็ตามคอมไพเลอร์ VB.NET ไม่สนับสนุนสิ่งนี้ มันสร้างฟิลด์สมาชิกส่วนตัวที่ซ่อนอยู่ซึ่งมองไม่เห็นใน IntelliSense:

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

ข้อมูลมากกว่านี้:

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


ทำไมคุณถึงอยากทำเช่นนั้น? ฉันนึกภาพไม่ออกว่าจะมีกรณีการใช้งานที่คุณจำเป็นต้องทราบจำนวนสมาชิกของกิจกรรมใน VB
Konrad Rudolph

ในบางสถานการณ์ C # จะมีข้อยกเว้นหากคุณยกเหตุการณ์ขึ้นและไม่มีตัวจัดการ VB.Net จะไม่ จึงจำเป็นต้องตรวจสอบ
Joel Coehoorn

2
ฉันใช้สิ่งนี้สำหรับเหตุการณ์วัตถุทางธุรกิจซึ่งส่งข้อความแสดงข้อผิดพลาดการตรวจสอบความถูกต้องให้กับสมาชิก ฉันต้องการตรวจสอบว่ามีการจัดการเหตุการณ์หรือไม่เพื่อที่ฉันจะได้ทราบว่ากำลังได้รับข้อผิดพลาดในการตรวจสอบความถูกต้อง มิฉะนั้นฉันมีวัตถุทางธุรกิจโยนข้อยกเว้น
Technobabble

2
การใช้งานที่มีประโยชน์อีกอย่างสำหรับสมาชิกส่วนตัวนี้คือการรับรายการเรียกใช้ของกิจกรรม ฉันเคยใช้มันในหลายกรณีเพื่อเริ่มต้นเหตุการณ์ในลักษณะที่ไม่ตรงกันกับผู้โทรทุกคน (ป้องกันไม่ให้ Listener A แก้ไขเหตุการณ์ก่อนที่ Listener B จะได้รับนอกจากนี้ยังป้องกันไม่ให้ Listener A ชะลอการส่งไปยัง Listener B) ฉันใช้สิ่งนี้มากในสถานการณ์การซิงค์ข้อมูลที่กำหนดเองและใน API ด้วย
STW

14

หากคุณต้องการชื่อตัวแปรเพื่อให้ตรงกับคำหลักให้ใส่วงเล็บ ไม่ใช่คอ. แนวทางปฏิบัติที่ดีที่สุด - แต่สามารถใช้อย่างชาญฉลาด

เช่น

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

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

เช่นตัวอย่างจากความคิดเห็น (@Pondidum):

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

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

ฉันคิดว่าตัวอย่างนี้จะดีกว่าถ้าคุณไม่ได้ใช้ "If" เป็นคีย์เวิร์ดตัวอย่าง
Sean Gough

4
จับเวลาเริ่มต้นและจับเวลาหยุดสปริงให้นึกถึงเป็นตัวอย่างของการใช้สิ่งนี้ให้ดี
Pondidum

5
+1 เพื่อชี้ให้เห็นด้วยข้อจำกัดความรับผิดชอบ มีคลาสเฟรมเวิร์กหลายคลาสที่ต้องการสิ่งนี้เพื่อแก้ไขอย่างถูกต้องเช่น [Assembly]
STW

5
[Enum] เป็นอีกตัวอย่างที่ดีของกรณีที่คุณต้องใช้วงเล็บเพื่อที่จะใช้คลาสแทนคำหลัก
Ryan Lundy

13

มีคำตอบสองสามคำเกี่ยวกับ XML Literals แต่ไม่เกี่ยวกับกรณีเฉพาะนี้:

คุณสามารถใช้ XML Literals เพื่อใส่สตริงลิเทอรัลที่จำเป็นต้องใช้ Escape สตริงลิเทอรัลที่มีเครื่องหมายอัญประกาศคู่

แทนสิ่งนี้:

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

คุณสามารถทำได้:

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

สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณกำลังทดสอบตัวอักษรสำหรับการแยกวิเคราะห์ 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>แท็กแน่นอนคุณสามารถใช้แท็กใดก็ได้ที่คุณต้องการ)


3
<q>จะเป็นแท็กที่ดีคล้ายกับการใช้งานใน Perl / Ruby อย่างไรก็ตามนั่นเป็นสำนวนที่ดีทีเดียว ชอบ!
Konrad Rudolph

ช่างเป็นความคิดที่ชาญฉลาด ขอบคุณ
Jeremy

12

DateTime สามารถเริ่มต้นได้โดยล้อมรอบวันที่ของคุณด้วย #

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

คุณยังสามารถใช้การอนุมานประเภทร่วมกับไวยากรณ์นี้ได้

Dim independanceDay = #7/4/1776#

ดีกว่าการใช้ตัวสร้างมาก

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

6
ไม่ใช่ถ้าคุณมี Option Strict On
danlash

12

คุณมีโค้ดได้ 2 บรรทัดในบรรทัดเดียว ด้วยเหตุนี้:

Dim x As New Something : x.CallAMethod

โอ้โฮ ... ฉันคิดว่านี่เป็นไปได้เฉพาะกับคลาสและมรดกเท่านั้น
Jason

อย่าลืมCall (New Something).CallAMethod()
Jonathan Allen

นี่คือผู้ถือครองจาก MS-Basic บน Apple] [! ในร้านของฉันฉันจะถูกเยาะเย้ยที่ใช้ Gotos: - /
FastAl

ส่วนใหญ่จะหลีกเลี่ยงเวลานี้ แต่ที่ฉันชอบใช้คือในกรณีงบที่เส้นสั้นจริงๆเช่น Case 4: x = 22
dwidel

11

พารามิเตอร์เสริม

ตัวเลือกนั้นง่ายกว่าการสร้างโอเวอร์โหลดใหม่มากเช่น:

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

1
ฉันไม่รู้ว่า C # กำลังจะได้รับพวกเขา เป็นสิ่งที่ดี แต่คุณต้องระมัดระวังในการใช้เฉพาะในกรณีที่คุณแน่ใจว่ารหัสจะไม่ถูกใช้โดย C # เนื่องจากไม่รองรับ FxCop / Code Analysis จะบอกให้คุณโอเวอร์โหลดเมธอดแทน
STW

... ฉันเพิ่งพบการใช้งานที่ยอดเยี่ยมสำหรับพารามิเตอร์เสริมในขณะที่ยังคงไม่ใช้รหัสการผลิต ฉันเขียนโพสต์สั้น ๆ เกี่ยวกับเรื่องนี้บนเว็บไซต์ของฉัน: yoooder.com/wordpress/?p=62
STW

2
อ่าฉันเกลียดสิ่งนี้มาก ... แต่มีประโยชน์สำหรับ Office อัตโนมัติ
dance2die

9

Title Case ใน VB.Net สามารถทำได้โดย VB6 fxn รุ่นเก่า:

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

1
มันยังอยู่ในคลาส textinfo ไม่แน่ใจว่าอยู่ในเนมสเปซอะไรน่าจะเป็น system.text
Shawn

คุณควรใช้ภาษา. net เป็นกลางและใช้คลาส Globalization TextInfo เพื่อแปลง ToTitleCase หากรหัสของคุณจำเป็นต้องแปลงเป็น C # คุณจะมีเรื่องน่ารังเกียจเล็ก ๆ น้อย ๆ มากมายที่ต้องใช้ Microsoft VisualBasic
Jeremy

9

คุณสมบัติที่มีพารามิเตอร์

ฉันได้ทำการเขียนโปรแกรม C # และค้นพบคุณลักษณะที่ขาดหายไปที่ VB.Net มี แต่ไม่ได้กล่าวถึงที่นี่

ตัวอย่างวิธีการทำเช่นนี้ (รวมถึงข้อ จำกัด c #) สามารถดูได้ที่: การใช้คุณสมบัติ get set ทั่วไปใน C # ... ด้วยพารามิเตอร์

ฉันได้ตัดตอนรหัสจากคำตอบนั้น:

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

สิ่งนี้น่าสนใจ แต่ฉันไม่แน่ใจว่ามันจะมีประโยชน์ตรงไหน myObj.Something ("abc") ดูเหมือนว่าคุณกำลังเข้าถึงฟังก์ชันมากกว่าคุณสมบัติ ไม่แน่ใจว่าสิ่งนี้ซื้ออะไรให้คุณ
mattmc3

ฉันเกลียดความคลุมเครือ ควรเป็นอย่างไร. วิธีการหรือคุณสมบัติ เครื่องมือปรับโครงสร้างบางอย่างแนะนำให้สร้างทั้งสองอย่างในบางสถานการณ์เช่นกันดูเหมือนว่าพวกเขาไม่รู้ด้วยซ้ำ ...
brumScouse
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.