PROGRAMMING WORKSHOP

.Net FrameWork,VB.Net |

Action Delegate, ForEach

Delegate를 만들어서 사용도 하지만 .NetFrameWork 시스템에 이미 만들어져서
내장되어 있는 것들이 있다
이것을 사용하면, Delegate 크래스를 만들고 구현할 필요가 없을 것이다
그림과 같이 .NetFrameWork의 구성원으로서 이미 만들어진 Function Delegate와
Sub Delegate를 볼수 있다



아래와 같이 사용하면
별도로 사용자정의 Delegate를 만들 필요 없이 System에 이미 준비된 Action Delegate와
Func Delegate를 사용할수 있다

Dim mySub = New Action(Sub() MsgBox("this is my first using Action Delegate"))
mySub.Invoke()

Action Delegate는 Sub Delegate를 말한다
본래는 System상에 아래와 같이 Delegate 크래스가 선언되어 있는 것이다

Public Delegate Sub Action
매개변수도 자유롭게 전달하게 아주 많이 준비되어 있는 것
Public Delegate Sub Action(Of In T)(obj As T)
...
Public Delegate Sub Action(Of In T1, In T2)(arg1 As T1,arg2 As T2)

...
...
...
이렇게 내부적으로 묵시적으로(implicitly) 선언된 Delegate들을
자신이 만든 Delegate같이 사용하면 되는 것이다

위의 Lambda expression으로 표현된 것을 AddressOf 로 별도의 프로시져에 한다면
아래와 같이 하겠지만..

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
	Dim mySub = New Action(AddressOf calledByDelegate)
	mySub.Invoke()
End Sub
Sub calledByDelegate()
	MsgBox("this is my first using Action Delegate")
End Sub

Lambda expression으로 한줄로 표현하는 것이 편리할 것이다
아무튼 항상 다양한 방법이 있는 것이고, 좋아하는 것을 사용하면 된다

왜 이런 내장된 Delegate같은 것이 필요한지,아래와 같은 활용을 보면 이해가 된다 집합체를 얼마나 쉽게 잘 활용할까??라는 문제가 항상 있는 것이고 이것을 이렇게 활용하는 것

Dim names As New List(Of String)
names.Add("사과")
names.Add("오렌지")
names.Add("바나나")
names.Add("애플")
names.Add("망고")
names.ForEach(Sub(q) MsgBox(q))

위의 빨강색 부분이 Action Delegate가 내부적으로 사용된것이지만

겉보기에는 생략된 것이다
Delegate의 역할이고 좀더 자세히 말하자면 Action Delegate의 활용인것이다
아래의 그림과같이 List개체의 ForEach( 메소드를 입력하려고 할때 도우미목록을 볼수 있을 것이다



아하..Lambda Expression으로 함수(function)도 넣을수 있고, 프로시져(sub)을 넣을수도 있고
AddressOf 로 별도의 프로시져를 전달할수도 있구나...
아하..그래서 이런 것을 이해하고
.NetFrameWork에서 제공하는 자원을 충분히 활용하기 위하여
앞페이지에서 주욱 장황하게
알지도 모를 복잡한 소리를 했구나...슬슬 감이 잡혀 오면서, 흠..할만한거네..
라는 말을 하게 되실 것이다

만약 위와 같은 집합체 List(Of T)를 전통적인 방법으로 하자면
For ~ Next 와 같은 순환문을 코딩하였을 것이지만
위와 같이 표현하면 집합체를 하나씩 Msgbox에 띄워준다
만약 VBA에서 한다면..아마도 이렇게 할 것이다

Dim names As New Collection
names.Add "사과"
names.Add "오렌지"
names.Add "바나나"
names.Add "애플"
names.Add "망고"

Dim varX As Variant
For Each varX In names
	Msgbox varX
Next

위의 표현은 Action Delegate에서 프로시져를 호출하지 않고
Lambda expression으로 인라인 코딩으로 처리한 것이다, 프로시져를
호출한다면...

Dim names As New List(Of String)
...
...
names.Add("바나나")
...
...
names.ForEach(AddressOf msgList)



Sub msgList(X)
	MsgBox X
End Sub

List개체의 ForEach라는 메소드에 프로시져를 전달 한셈이다
VBA로 하던 무엇으로 하던, 목적한바의 작업을 하는데는 지장없다
언어를 발전시키는 이유는 좀더 쉽고, 편하게 하자는 것
쉽고, 편하고 싶으면 능력을 확장시키는 것이고, 그렇지 않으면
지루하고 신이 안난다..

Action Delegate에 좀더 많은 매개변수를 전달해 보고 구현해 보자

 Dim mySub = New Action(Of String, Integer, Integer)(Sub(sX, iX, iY)
							Dim sMsg As String = ""
							For iX_ As Integer = 1 To iX
								For iY_ As Integer = 1 To iY
									sMsg &= sX
								Next
								sMsg &= vbNewLine
							Next
							MsgBox(sMsg)
							End Sub)
mySub.Invoke("A", 10, 10)

AddressOf 로 별도의 프로시져를 연결해도되지만
Lambda Expression을 자주 사용하게 될 것이니, 직접입력하면서
숙달시키시기를..



***[LOG-IN]***

Func Delegate

이제 함수를 해보자
Func Delegate를 활용해 보자
아래와 같이 하면

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
	Dim myFunc As Func(Of String, String) = AddressOf x
	MsgBox(myFunc("A,B,C,D,E,F,G"))
End Sub
Function x(sX As String) As String
	Return String.Join(",", sX.Split(",").Reverse)
End Function

위의 것을 AddressOf 하여 별도의 함수를 포인팅하지 않고
Lambda expression으로 하면..

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Dim myFunc As Func(Of String, String) = Function(x) String.Join(",", x.Split(",").Reverse)
        MsgBox(myFunc("A,B,C,D,E,F,G"))
End Sub

함수(Func delegate)는 항상 매개변수중 마지막 매개변수는 리턴값을 위한 것이다
프로시져(Action delegate)는 리터값이 없지만, 함수는 리턴값을 얻기 위한 것이니까..
아래와 같이 매개변수 3개가 전달되면 마지막 하나는 리턴값

Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
	Dim myFunc As Func(Of String, Integer, String) = Function(x, y) x.Split(",")(y)
	MsgBox(myFunc("Apple,Mango,Banana,Orange,Grape", 2))
End Sub

***[LOG-IN]***