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 as sqlException where 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

커스텀 Enums

VB 의 진짜 숨겨진 기능 중 하나는 확장 된 기능을 가진 completionlist고유 한 Enum유형 을 만드는 데 사용할 수있는 XML 문서 태그입니다 . 하지만이 기능은 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

이제으로 선언 된 변수에 값을 할당 할 때 RuleIDE는에서 가능한 값의 IntelliSense 목록을 제공합니다 RuleTemplates.

/편집하다:

이것은 IDE에 의존하는 기능이기 때문에 이것을 사용할 때 어떻게 보이는지보기는 어렵지만 스크린 샷 만 사용하겠습니다.

작업 완료 목록 http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

실제로 IntelliSense는 .NET Framework를 사용할 때 얻는 것과 100 % 동일합니다 Enum.


흥미 롭습니다-이것을 소비했을 때 어떻게 보이는지 예를 보여줄 수 있습니까?
Brian MacKay

누군가가 Rule 생성자를 직접 호출하여 자신의 규칙을 만들 수있는 것 같습니다. 그렇다면이를 중지하고 싶다면 라이브러리에서 생성자를 "Friend"로 선언 할 수 있습니까?
Joel Coehoorn

Joel, 내 예제 코드에서 나는 의도적으로 이것을 금지하지 않았습니다. 오히려 사용자에게 몇 가지 공통 규칙을 제공하고 고유 한 특수 규칙을 만들 수 있습니다. 물론 생성자를 표시 friend하거나 enum : Rule대신 동일한 클래스를 사용하여 이를 방지 할 수 있습니다 RuleTemplate.
Konrad Rudolph

숨겨진 유용한 속성 사용 목록이있는 어딘가에 있습니까? 이것은 믿을 수 없을 것 같지만, 내가 그것을 어디에서 사용할지 또는 어떤 경우에 열거 형으로 제한되는 제네릭을 가질 능력이없는 주요 불만을 해결할 수 있는지 아직 확실하지 않습니다.
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

우우우 우우우 우우우! 감사! 굉장하네요! ELinq, DLinq에서도 작동합니까? XLinq는 어떻습니까?
Shimmy Weitzhandler

@dotjoe 흠? 이 글롭에 대해 '게으른'것은 없습니다.
Josh Lee

이것이 어떻게 수행됩니까? 내부적으로 무슨 일이 일어나고 있습니까? 정규식 라이브러리의 동의어입니까?
brumScouse

48

Typedef

VB는 별칭 을 typedef통해 원시적 인 종류를 알고 있습니다 Import.

Imports S = System.String

Dim x As S = "Hello"

제네릭 유형과 함께 사용할 때 더 유용합니다.

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

2
내 IDE에서 Import라는 단어가 인식되지 않는 예를 보여주세요.
Shimmy Weitzhandler

5
Imports그것은해야한다. ;-) 어쨌든,이 오류는 거의 1 년 동안 감지되지 않고 28 개의 찬성표를 얻었습니다.
Konrad Rudolph

나는 항상 제네릭에 대한 기본값을 가진 새로운 "유형"을 어떻게 만들 수 있는지 궁금했다! 멋있는!
eidylon

3
Import, Imports, Importz, 무엇이든! Sheesh, 당신은 우리가 그들을 찬성하기 전에이 게시물 을 읽었다 고 생각 합니다!
MarkJ

비주얼 스튜디오 테스트에서 xunit을 사용하기에 아주 좋습니다. 예Imports Assert = xUnit.Assert
wheelibin

45

오! XML 리터럴을 잊지 마세요 .

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 리터럴을 사용하여 추악한 문자열 이스케이프를 피할 수 있습니다 (예 : 큰 따옴표가 포함 된 문자열을 사용할 때). 그냥 XML 리터럴 내부 문자열을 넣어 같은 값을 호출합니다 <string>This string contains "quotes" and it's OK.</string>.Value . (나는이 모든 필드가 따옴표로했다 CSV 파일을 구문 분석에 대한 테스트를 작성할 때 특히 유용 그것은 것 발견 되지 에서 손으로 모든 따옴표를 탈출 할 수 있었다 재미를 내 테스트 라인.)
Ryan Lundy

2
@Kyralessa : +1, 좋은 댓글입니다. 사실, 여러 줄 문자열을 지정하는 좋은 방법이기도합니다 (SQL 문을 포용하는 등).
Heinzi 2009

인라인 XML은 사상 최악의 VB.NET 기능 중 하나입니다. 입증되지 않은 사실.
Grant Thomas

39

객체 초기화도 거기에 있습니다!

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

1
나는 그들이 중괄호로 갔다는 것을 믿을 수 없습니다. 우리는 이미 With 문을 가지고 있습니다. 그들은 그 구문을 재사용 할 수있었습니다.
Sam Ax

2
나는 JK 롤 ...이 도로에는 경찰이 없음을 보여주기 위해 방금 만든거야, 알
흔들 Weitzhandler

4
모든 컴파일러 작성자가 그 자체로 C / C ++ 프로그래머 일 때 일어나는 일입니다. 그들은 더 나은 것을 생각할 수 없기 때문에 C 구문을 다른 언어로 계속 밀어 넣습니다.
RBarryYoung

38

DirectCast

DirectCast놀랍습니다. 표면적 CType으로는 객체를 한 유형에서 다른 유형으로 변환한다는 점 에서 연산자 와 유사하게 작동합니다 . 그러나 훨씬 더 엄격한 규칙에 따라 작동합니다. CType따라서의 실제 동작은 종종 불투명하며 어떤 종류의 변환이 실행되는지 전혀 분명하지 않습니다.

DirectCast 다음 두 가지 작업 만 지원합니다.

  • 값 유형의 개봉 및
  • 클래스 계층 구조에서 업 캐스팅.

다른 모든 캐스트는 작동하지 않으며 (예 :에서 Integer에 대한 unbox를 시도하는 경우 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나는 주로 .NET을 널리 사용하여 골라 낼 뼈가 있었기 때문에 그 당시에 언급하지 않은 것은 부끄러운 일 입니다 CType.
Konrad Rudolph

@Maslow : 물론 그렇지 않습니다. Enum은 값 유형이고 TryCast문서에 따라 참조 유형에서만 작동하기 때문입니다.
Konrad Rudolph

+1 : 헤. 인정해야합니다.이 글을 읽고 "예, DirectCast, 어떻게 잊었습니까?"라고 생각했습니다. 그리고 나서 바로 다음 코드 줄에서 사용했습니다 (CType이 정말 싫어서).
RBarryYoung

37

If 조건부 및 통합 연산자

어떻게 숨겨 졌는지 모르겠지만 Iif ([expression], [value if true], [value if false]) As 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
@Slough, 말도 안돼. 이 메서드는 100 % 형식 안전하며 (두 번째 및 세 번째) 인수와 동일한 형식의 개체를 반환합니다. 또한 인수간에 확장 변환이 있어야합니다. 그렇지 않으면 유형이 일치하지 않기 때문에 컴파일 오류가 발생합니다.
Konrad Rudolph

1
예, 유형 안전하지 않은 IIf ()
Pondidum

2
@ Br.Bill 실제로 C 및 Perl의 연산자 와 완전히 동일:? 하며 단순한 버전이 아닙니다.
Konrad Rudolph 2011 년

32

이것은 좋은 것입니다. VB.Net 내의 Select Case 문은 매우 강력합니다.

물론 표준이 있습니다.

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
실제로 몇 가지를 놓쳤습니다. a) 하나 이상의 변수를 테스트하기 위해 "Select Case True"사용, b) "Case A, B, ..."양식 사용, 심지어 c) in-에 ":"적용 실행 문을 조건 절로 줄입니다 (많은 사람들이 이것을 좋아하지 않음).
RBarryYoung

6
Select Case True를 사용하지 마십시오. If 문을 사용하십시오.
Ryan Lundy

4
Select Case True는 거대한 ifelse 문보다 읽기가 훨씬 쉽습니다.
dwidel 2010

와 문제는 Select Case True이 때문이다 보인다 는 평가 것처럼 각각Case진술 및 사실 각각의 코드를 실행합니다. 그러나 실제로는 하나씩 평가하고 사실 인 첫 번째 코드에 대해서만 코드를 실행 합니다. 의 구문 If은 이와 관련하여 훨씬 더 명확합니다 ( If...Else If...Else If...Else).
Ryan Lundy 2011

31

내가 항상 사용하는 주요 시간 절약 방법 중 하나는 With 키워드입니다.

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

나는 내가해야하는 것보다 더 많이 입력하는 것을 좋아하지 않는다!


그러나 그것은 또한 몇 가지 숨겨진 버그를 생성합니다. 특히 With에 With가있을 때
Varun Mahajan

2
기존 With에 새 With를 넣을 수 있다는 것도 몰랐습니다. 그것은 단지 조잡합니다!
Bob King

2Bob : 조잡하지 않습니다. 제 생각에는 .. 조심스럽게 사용하는 언어 구조 일뿐입니다. 연속적인 줄에 많은 속성을 설정하는 것은 좋지만 복잡한 코드에서 임의의 .Foo를 찾은 다음 위의 With 문 x 줄을 찾아야하는 것은 기능을 잘 사용하지 않습니다.
ChrisA

2
C #에이 기능이 있습니까? 아니면 잠 들어 있었고 이미 C # 숨겨진 기능에 대한 답변이 있습니까? ;-)
peSHIr

1
@ 부 : 당신 말이 맞지만 감시 목록에 추가 할 수 없다는 것은 여전히 ​​성가신 일입니다.
Meta-Knight

31

가장 쉽고 간편한 CSV 파서 :

Microsoft.VisualBasic.FileIO.TextFieldParser

Microsoft.VisualBasic에 대한 참조를 추가하면 다른 .Net 언어 (예 : C #)에서 사용할 수 있습니다.


5
+1 C # 사람들이 이것을 고려하지 않고 FileHelpers를 실행하는 방법은 이상합니다. FileHelpers가 우수하다고 확신하지만 외부 종속성입니다.
MarkJ

@MarkJ 나는 그것 때문에 무지의 가정
나단 쿠프

나는이 수업을 찾으려고 시도하면서 지옥을 봤지만 결코하지 않았습니다. 신고 해 주셔서 감사합니다!
pingoo


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 

또한 이것은 단순히 클래스의 Shared 멤버로 선언하는 것과 동일하지 않습니다. 이 방법으로 선언 된 항목도 스레드로부터 안전합니다. 이 시나리오에서는 표현이 절대 변경되지 않기 때문에 문제가되지 않지만 다른 경우가있을 수 있습니다.


1
이것의 한 가지 용도는 메서드가 호출 될 때마다 증가하는 카운터를 유지하는 것입니다. 변수가 Static으로 표시되면 각 메서드 호출에서 다시 초기화되지 않습니다. 첫 번째 호출에서만 초기화되며 그 이후에는 그 값을 유지합니다.
Ryan Lundy

이 이유는 정적 클래스 멤버라는 VB.NET에서 "공유"하는 이유입니다
엔리코 캄 피돌 리오

정적은 VB.NET에서 클래식 VB보다 훨씬 더 나쁜 형태입니다. 정적 변수는 가능할 때마다 피해야합니다.
Sam Ax

6
@Boo-꽤 휩쓸리는군요. 당신의 정당성은 무엇입니까? 정적 변수가 유용하다고 생각합니다.
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"네임 스페이스 가 정말 마음에 듭니다 . My 는 여러 정보 및 기능 그룹에 대한 바로 가기입니다. 다음 유형의 정보에 대한 빠르고 직관적 인 액세스를 제공합니다.

  • My.Computer : 파일 시스템, 네트워크, 장치, 시스템 정보 등 컴퓨터와 관련된 정보에 액세스합니다. My.Computer.Network, My.Computer.FileSystem 및 My를 포함하여 매우 중요한 여러 리소스에 대한 액세스를 제공합니다. . 컴퓨터. 프린터.
  • My.Application : 이름, 버전, 현재 디렉토리 등 특정 응용 프로그램과 관련된 정보에 액세스합니다.
  • My.User : 현재 인증 된 사용자와 관련된 정보에 접근합니다.
  • My.Resources : 강력한 형식으로 리소스 파일에 상주 하는 응용 프로그램에서 사용하는 리소스에 액세스합니다.
  • My.Settings : 강력한 입력 방식으로 애플리케이션의 구성 설정에 액세스합니다.

이것은 대단하고 모든 vb.net 사람은 내 네임 스페이스에있는 내용을 알아야합니다. 매우 유용합니다.
박사. 악

My. * 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로, 해시 테이블에 (키, 값) 쌍을 추가 한 다음 키를 사용하여 값을 검색 할 수 있습니다. 예를 들어, 다음 코드는 3 개의 항목을 해시 테이블에 추가하고 "Pork"키를 사용하여 그 중 하나를 찾습니다.

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
흥미롭지 만 실제로 유용하지는 않습니다. 이것이 yield 키워드와 같은 누락 된 기능을 추가하는 대신 VB 팀이 작업하는 종류입니까? : P
Meta-Knight

5
이 기능은 VB3 (AFAIK)에서 이전 버전과의 호환성을 위해 전달되었습니다
Eduardo Molteni

1
키 인덱스를 구현하는 클래스는 상속받은 공통 인터페이스를 가지고 있습니까? IKeyed와 같은 방식으로 정수 인덱스 컨테이너가 IENumberable을 구현합니까?
Maslow

2
이 기능은 LINQ to DataSets에서 매우 편리한 DataRows (예 : dr! ID)에서도 작동합니다.
Paul

19

이것은 기본 제공되며 C #보다 확실한 이점입니다. 동일한 이름을 사용하지 않고 인터페이스 메서드를 구현하는 기능.

예 :

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

End Sub

C #에서 이와 같은 작업을 할 수 있다고 확신합니다. VB.NET에서는 강제로, C #에서는 선택 사항입니까?
Jesper Blad Jensen

5
하위를 비공개로 만들 수도 있습니다. 이는 비 일반적으로 사용되지 않는 인터페이스 버전에 대한 호출과 같은 항목을 숨기는 좋은 방법입니다.
Craig Gidney

3
좋은 생각이 될 수 있습니다. 고전적인 예는 IDisposable에 대한 Dispose 구현 역할도하는 Public Close 메서드를 원하는 경우입니다.
MarkJ

1
메서드 이름을 공유하는 두 개의 인터페이스를 구현하는 경우에도 매우 유용합니다.
Eric Nicholson

나는 이것을 보았고 항상 내가 보지 않았기를 바랐다. 허용되지 않아야합니다.
FastAl

17

ByVal 강제

VB에서 인수를 추가 괄호로 묶으면 메서드의 ByRef 선언을 재정의하고 ByVal로 바꿀 수 있습니다. 예를 들어 다음 코드는 4,5,6 대신 4, 5, 5를 생성합니다.

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
오, 세상에 .. 다른 사람의 코드로 읽어 보면 무슨 일이 벌어 졌는지 알 수 없을 것 같지만 그건 놀라운 기능입니다. 그것이 무엇을하고 있는지 알기 위해 주석을 달아야한다면, 대신 전달하기 위해 throw away 변수를 만들었을 것입니다.
mattmc3

7
이것은 실제로 괄호 사용의 부작용입니다. 괄호는 하나의 항목이더라도 내부 내용의 임시 값을 생성합니다. 이 효과 KILLED ME in vb6-Sub 호출은 괄호를 사용하지 않았지만 C에서 온 나는 본능적으로 괄호를 넣었습니다. 6.0은 여러 매개 변수에 대해 폭발했지만 하나의 매개 변수 subs에 대해 행복하게 임시 값을 전달하고 내 '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
확실히 매우 너무 많은 인수를 취하는 방법을 발생 편리한 도구. 각 매개 변수의 이름을 지정하고 자체 행에 name : = value를 입력하려고합니다. 5 개 이상의 매개 변수를 사용하는 메서드의 경우 훨씬 더 직관적이고 깔끔합니다.
STW

수십 개의 선택적 인수가있는 메서드를 처리해야하는 Office 자동화에 특히 유용합니다.
MarkJ

1
또한 멋진 점은 두 가지를 혼합 할 수 있다는 것입니다 . 필요한 매개 변수를 순서대로 지정하여 시작한 다음 선택적 인수에 대해 명명 된 매개 변수로 전환합니다!
RBarryYoung

15

Using 문은 VB 8의 새로운 기능이며 C #은 처음부터 사용했습니다. 자동으로 dispose를 호출합니다.

Using lockThis as New MyLocker(objToLock)

End Using

23
하나의 Using 문이 여러 Disposable 개체를 래핑하도록 할 수 있다는 점은 주목할 가치가 있습니다 (적어도 두 번 잊었 기 때문에). 구문은 "Using objA as new object, objB as new object ...."입니다. 여러 Using 문을 중첩하는 것보다 훨씬 깔끔합니다.
STW

확실히 내가 좋아하는 것 중 하나입니다.
Sam Ax

14

가져 오기 별칭도 거의 알려지지 않았습니다.

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
우리도 같은 생각을했다고 생각합니다.
chrissie1

3
@Boo-여기에 가져 오기 별칭이 악하지 않은 간단한 예가 있습니다. 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
이 비공개 멤버의 또 다른 편리한 용도는 이벤트의 호출 목록을 가져 오는 것입니다. 모든 호출자에게 비동기 방식으로 이벤트를 발생시키기 위해 여러 경우에 사용했습니다 (리스너 B가 이벤트를 수신하기 전에 리스너 A가 이벤트를 수정하는 것을 방지합니다. 또한 리스너 A가 리스너 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
timer.Start 및 timer.Stop 봄을 염두에 두는 좋은 사용 사례
Pondidum

5
면책 조항으로 지적하면 +1. [Assembly]
STW

5
[Enum]은 키워드 대신 클래스를 사용하기 위해 대괄호가 필요한 경우의 또 다른 좋은 예입니다.
Ryan Lundy

13

XML 리터럴에 대한 몇 가지 답변이 있지만이 특정 경우에 대한 답변은 없습니다.

XML 리터럴을 사용하여 그렇지 않으면 이스케이프해야하는 문자열 리터럴을 묶을 수 있습니다. 예를 들어 큰 따옴표를 포함하는 문자열 리터럴입니다.

대신 :

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

정말 천재적인 아이디어입니다. 주셔서 감사합니다
제레미

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

한 줄에 두 줄의 코드를 만들 수 있습니다. 그 후:

Dim x As New Something : x.CallAMethod

워 ... 난이 유일하게 가능한 승 / 클래스와 상속 줄 알았는데
제이슨

잊지 마세요Call (New Something).CallAMethod()
Jonathan Allen

이것은 MS-Basic on the Apple] [! 내 가게에서 나는 Gotos를 사용하는 것과 마찬가지로 조롱을받을 것입니다. :-/
FastAl

대부분의 경우 이것은 피해야하지만 내가 사용하고 싶은 곳은 줄이 정말 짧은 case 문입니다. 예 : 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
아, 이건 정말 경멸합니다 ...하지만 사무 자동화에 유용합니다
dance2die 2009-10-20

9

VB.Net의 타이틀 케이스는 이전 VB6 fxn으로 얻을 수 있습니다.

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

1
textinfo 클래스에도 있습니다. 어떤 네임 스페이스에 있는지 확실하지 않습니다. 아마도 system.text
Shawn

.net 언어 중립적이며 Globalization TextInfo 클래스를 사용하여 ToTitleCase를 변환하는 것이 좋습니다. 당신이 코드는 지금까지의 C #으로 변환 할 필요가 있다면 당신은 Microsoft.VisualBasic을 필요로 작은 악성 콘텐츠를 많이해야합니다
제레미

9

매개 변수가있는 속성

저는 C # 프로그래밍을 해왔고 VB.Net에없는 기능을 발견했지만 여기서는 언급하지 않았습니다.

이 작업을 수행하는 방법의 예 (C # 제한 사항 포함)는 다음에서 볼 수 있습니다. 매개 변수와 함께 C #에서 일반적인 get set 속성 사용 ...

그 답변에서 코드를 발췌했습니다.

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 2010-08-25
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.