VB.Net 흐름 제어(Flow Control) 익히기

VNote 2017.06.18 10:43:45 *:

http://yaraba.tistory.com/71

 

1. If 조건문

If문은 조건에 따라 문장을 처리해야할 때 사용하며 가장 가단한 사용 방법은 아래의 예와 같이 "If 조건 Then 처리문장"의 형식으로 한 줄에 특정 조건을 만족할 때의 처리 문장을 간단하게 기술하는 것입니다.

1

2

3

Dim Blocks As New List(Of String)

If Hours <> 0 Then Blocks.Add(Hours & " h")

If T.Minutes <> 0 Then Blocks.Add(T.Minutes.ToString & " m")

 

조건이 참일때와 거짓일 때를 구분해서 처리할 경우에는 아래의 예와 같이 Else문 다음 줄에 거짓일 경우에 처리할 문장을 기술하고  End If로 조건문을 닫아주면 됩니다.

1

2

3

4

5

6

If CommandLine.Silent Then

    ProgramConfig.LogAppEvent(String.Format("Silent: Balloon: [{0}].", Msg))

    Exit Sub

Else

    ProgramConfig.LogAppEvent(String.Format("Balloon tip shown: [{0}].", Msg))

End If

 

Then 또는 Else 다음 줄에 기술하는 문장은 여러 문장을 여러 줄에 기술할 수 있습니다. 그 내부에 또다른 If 조건문이 들어 갈수도 있고(Nested) 그 사용 방법은 동일합니다. 아래의 코드를 보면 Then문 안에 또다른 If문 블럭을 기술하고 있는 것을 확인할 수 있습니다. 비주얼스튜디오가 자동적으로 들여쓰기(Indentation)를 지원해 주지만 코드의 가독성이 훼손되지 않도록 들여쓰기를 잘 해주시는 것이 좋습니다.

1

2

3

4

5

6

7

8

9

10

11

12

If e.KeyCode = Keys.Enter Then

    If Actions.SelectedIndices(0) = 0 Then

        Actions.LabelEdit = True

        Actions.SelectedItems(0).BeginEdit()

    Else

        Dim Bounds As Drawing.Rectangle = Actions.SelectedItems(0).Bounds

        ActionsMenu.Show(Actions, New Drawing.Point(Bounds.Left, Bounds.Top))

    End If

ElseIf e.KeyCode = Keys.F2 And Actions.SelectedIndices(0) <> 0 Then

    Actions.LabelEdit = True

    Actions.SelectedItems(0).BeginEdit()

End If

 

위의 예제를 보면 ElseIf문을 사용했는데 Else문 다음에 또다른 If문을 작성해서 코드를 복잡하게 만들지 않고 연쇄적인 If문 작성을 가능하게 하고 ElseIf문 다음의 Then문 Else문은 동일하게 올 수 있고 연쇄적으로 ElseIf문이 또다시 올 수도 있습니다. 단, ElseIf문은 앞서 사용한 If문의 연장선상에 있으므로 반드시 End If로 문을 끝내주어야 합니다. 또한 많은 ElseIf를 사용해야 한는 경우는 아래에서 다룰 Select문을 검토하는 것이 코드의 가독성을 높이고 버그를 줄이는 방법입니다. 

 

 

2. Select 문

하나의 조건 비교에 여러 처리 방법이 있는 경우에 적절한 구문입니다. 문장 형식은 아래와 같습니다.

Select Case 조건식

    Case 비교식

        처리문장

    Case 비교식

        처리문장

    Case Else

        처리문장

End Select

Case 비교식은 경우수 만큼 기술하고 나머지 경우의 수는 Case Else문에 다음에 기술합니다. 일반적으로 Case 비교식에는 리터럴 값을 기술하지만 "10 To 20", "Is < 10"처럼 값의 범위를 지정할 수 있습니다. 

 

1

2

3

4

5

6

7

8

9

10

11

Select Case e.KeyCode

    Case Keys.N

        Actions.LabelEdit = True

        Actions.Items(0).BeginEdit()

    Case Keys.O

        Interaction.StartProcess(ProgramConfig.ConfigRootDir)

    Case Keys.L

        SetView(1)

    Case Keys.Subtract

        SetFont(Actions.Font.Size - 1)

End Select

아래의 코드는 Case Is와 Case Else를 사용한 또다른 예제입니다. 

1

2

3

4

5

6

7

8

9

10

Select Case Size

    Case Is >= (1 << 30)

        Return Math.Round(Size / (1 << 30), Digits).ToString & " GB"

    Case Is >= (1 << 20)

        Return Math.Round(Size / (1 << 20), Digits).ToString & " MB"

    Case Is >= (1 << 10)

        Return Math.Round(Size / (1 << 10), Digits).ToString & " kB"

    Case Else

        Return Math.Round(Size, Digits).ToString & " B"

End Select

C언어 switch 문에서는 case구문 다음에 break문을 기술하지 않으면 다음 case로 흘러버리지만 VB에서는 해당 Case문만 수행하고 End Select다음으로 나오는 차이점이 있습니다.

 

조건에 따라 다른 값을 설정해야 하지만 If나 Select를 사용하지 않고 간편하게 문장을 기술하고 싶을 경우에는 Microsoft.VisualBasic.Switch(조건, 값, 조건, 값......) 구문을 사용할 수 있습니다. 조건이 참을 경우 그에 해당하는 값을 리턴해 줍니다.

 

 

3. For 루프

많은 프로그래밍 언어에서 사용하는 for 루프는 VB에서는 "For 인덱스 = 시작 To 끝 Step 증분"으로 기술하고 루프의끝에는 "Next 인덱스"와 같이 기술합니다. 인덱스 변수 값에 "시작"을 입력하고 인덱스 값이 "시작"과 "끝" 값 사이에 있을 동안 루프를 반복합니다. 루프를 반복할 때 때 인덱스에 "증분"을 더하는데 Step문을 생략하면 증분은 1로 간주합니다. Next문의 인덱스는 생략할 수 있지만 프로그램의 가독성을 위해서 Next 다음에 인덱스 이름을 붙여줍니다. 인덱스는 For문 이전에 먼저 선언해 주지만 선언하지 않은 상태에서 For문에 "For 인덱스 As 데이터타입"의 형식을 사용 시점에 정의해서 사용할 수도 있습니다. 물론 다른 문장처럼 내부에 또다른 For 문을 내장할 수 있습니다. 다음은 그 사용 예제입니다. 인덱스를 For 구문에서 선언했고 증분을 음수로 해서 역순으로 작업하고 있습니다. For 루프 수행 도중 루프에서 빠져나갈 때는 "Exit For"구문을 사용합니다.

1

2

3

4

5

For ProfileIndex As Integer = ScheduledProfiles.Count - 1 To 0 Step -1

    If Not Profiles.ContainsKey(ScheduledProfiles(ProfileIndex).Name) Then

        ScheduledProfiles.RemoveAt(ProfileIndex)

    End If

Next ProfileIndex

 

 

4. For Each 루프

배열이나 트리 노드 처럼 특정 데이터 타입의 항목으로 구성된 집합 변수를 "For 인덱스"문을 사용하지 않고 간편하게 처리할 수 있는 방법입니다. 항목의 개수나 배열의 크기를 고민할 필요없이 For Each 구문이 자동적으로 개별 항목 하나 하나를 가져다 주므로 프로그래머는 해당 개별 항목에 대한 처리만 수행하면 됩니다. 문법은 "For Each 항목 In 집합변수"로 시작하고 루프의 끝은 "Next 항목"으로 기술합니다. For문과 같이 항목을 앞에서 선의하지 않은 경우에는 "As 데이터타입"으로 For Each문에서 정의할수 있고 루프를 중간에서 끝내고 싶은 경우에는 "Exit For"구문을 사용합니다. 다음은 그 사용 예제입니다. 이 예제에서는 루프 중간에 Exit For로 루프를 빠지는 경우가 있습니다.

1

2

3

4

5

6

7

For Each Node As TreeNode In BaseNode.Nodes

    If Node.Text = Path(0) Then

        Node.Expand() : Path.RemoveAt(0)

        CheckAccordingToPath(Node, Path, FullCheck)

        Exit For

    End If

Next Node

반대로 루프 수행중 루프의 나머지 문장을 수행하지 않고 다음 루프로 건너뛰고 싶을 때는 "Continue For"문을 사용할 수 있습니다.

1

2

3

4

5

6

7

8

9

10

11

12

For Each Folder As String In WriteNeededFolders

    If Not IO.Directory.Exists(Folder) Then Continue For

 

    Dim TestPath As String = Folder

    IO.File.Create(TestPath).Close()

    ToDelete.Add(TestPath)

 

    If Folder = Application.StartupPath Then Continue For

    For Each File As String In IO.Directory.GetFiles(Folder)

        If (IO.File.GetAttributes(File) Then Throw New IO.IOException(File)

    Next

Next

 

 

5. While 루프

"While 조건식"으로 반복할 루프를 시작하고 "End While"로 루프를 마감합니다. 지정한 조건식이 참일 동안 루프를 반복합니다. for문 처럼 "Exit While", "Continue While" 문을 사용할 수 있습니다.

1

2

3

4

5

6

7

8

While Not LogReader.EndOfStream

    Dim Line As String = LogReader.ReadLine()

    If TitleLine.IsMatch(Line) Then

        Archives.Add(New Text.StringBuilder())

        If Archives.Count > MaxArchivesCount Then Archives.RemoveAt(0)

    End If

    If Archives.Count > 0 Then Archives(Archives.Count - 1).AppendLine(Line)

End While

 

 

6. Do While/Until 루프

Do 루프는 End 대신 Loop문으로 루프를 마감합니다. Do 루프가 다른 루프와 다른 차이점은 조건식을 Do 옆에 두어 루프 진입 시점에 먼저 비교할 수도 있고 Loop 옆에 두어 루프를 실행한 다음 비교 할 수도 있다는 점입니다. 조건 비교를 나중에 하는 방식은 일단 루프를 한번은 수행해야 하는 상황에 적절합니다. 조건은 While과 Until 두가지 방식으로 지정할 수 있으며 While은 조건식이 참일 동안 루프를 수행하고 Until은 조건식이 거짓일 동안 루프를 반복하고 참이면 루프를 빠집니다. 다른 루프와 같이 루프를 빠질 때는 "Exit Do"문을 사용합니다.

 

1

2

3

4

Do

    TempDest = DestFile & "-" & IO.Path.GetRandomFileName()

    DestBack = DestFile & "-" & IO.Path.GetRandomFileName()

Loop While IO.File.Exists(TempDest)

 

 

7. With 문

With문은 프로그램의 흐름 제어라기 보다는 프로그램 작성을 편리하게 할 수 있도록 돕는 구문입니다. 특히 .Net 프레임워크의 여러가지 기능과 자원을 활용하다 보면 다양한 오브젝트를 참조해야 하는데 오브젝트 참조 표현의 반복되는 부분을 With 구문으로 묶어서 짧고 간편하게 표현할 수 있도록 한 것입니다. 아래의 예제 코드를 보면 noise라는 오브젝트에 있는 Filters를 참조하는 여러 문장을 With End With로 묶고 그 내부에서는 With 옆에 기술한 오브젝트를 생략한 것을 확인 할 수 있습니다.

1

2

3

4

5

6

7

8

9

Dim noise As New AviSynthCategory("Noise")

 

With noise.Filters

    .Add(New AviSynthFilter(noise.Name, "FluxSmooth Low", "FluxSmoothT(2)", True))

    .Add(New AviSynthFilter(noise.Name, "FluxSmooth Medium", "FluxSmoothT(4)", True))

    .Add(New AviSynthFilter(noise.Name, "FluxSmooth Heavy", "FluxSmoothT(8)", True))

    .Add(New AviSynthFilter(noise.Name, "Deen", "Deen()", True))

    .Add(New AviSynthFilter(noise.Name, "UnDot", "UnDot()", True))

End With

 

 

8. Using 문

With와 같이 흐름 제어라기 보다는 시스템 자원을 편리하게 사용할 수 있도록 돕는 구분입니다. 파일, 데이터베이스, 시스템 오브젝트 등과 같이 자원 가져오기-사용-해제의 과정이 필요한 것들에 대해서 "Using 자원변수 As New 자원 타입"의 형태로 시작하고 "End Using"으로 닫으면 사용했던 자원을 자동으로 해제합니다. 다음은 그 사용 예입니다.

1

2

3

4

Using DataStream As New IO.StreamReader(Path), _

          CryptObject As New System.Security.Cryptography.MD5CryptoServiceProvider()

    Return Convert.ToBase64String(CryptObject.ComputeHash(DataStream.BaseStream))

End Using

 

 

9. End 문

흐름 제어의 중요한 부분으로 프로그램을 종료시키는 구문입니다. 프로그램의 종료까지 자연스럽게 흐르거나 주요 Form을 닫는 이벤트 처리가 있으면 필요 없는 구문이지만 실행 중간에 임의로 프로그램을 종료시킬때 사용합니다.