728x90
반응형
1. Delegate Combine
using System;
class Test {
public static int Method1() {
Console.WriteLine("Method1");
return 1;
}
public static int Method2() {
Console.WriteLine("Method2");
return 2;
}
public static int Method3() {
Console.WriteLine("Method3");
return 3;
}
public static int Method4() {
Console.WriteLine("Method4");
return 4;
}
}
delegate int FUNC();
class Program {
public static void Main() {
FUNC f1 = Test.Method1;
FUNC f2 = Test.Method2;
FUNC f3 = Test.Method3;
// 1. Delegate Combine
FUNC f4 = (FUNC)Delegate.Combine(f1, f2); // - ok
// FUNC f4 = (FUNC)Delegate.Combine(f1, f2, f3); - ok
// FUNC f4 = (FUNC)Delegate.Combine(f1, Test.Method4); - error
f4(); // Method1, Method2 호출
// 2. +, -, +=, -=
FUNC f5 = f1 + f2; // - ok
// FUNC f5 = f1 + f2 + f3; - ok
// FUNC f5 = f1 + Test.Method4 + f2; - ok
f5(); // Method1, Method2 호출
}
}
① Delegate.Combine(delegate1, delegate2, ...)
=> 기존의 delegate를 결합한 새로운 delegate 객체 반환
=> Method 이름을 직접 사용할 수는 없음
② +, +=, -, -= 연산자
=> Delegate 이름 또는 Method 이름을 사용한 결합
③ Delegate는 immutable 하다.
=> 기존의 delegate 객체에 추가되는 것이 아닌 새로운 delegate 객체를 생성하는 것
delegate는 reference type이다.
FUNC f6 = Test.Method1; 으로 객체를 만들고
FUNC f7 = f6; 으로 복사한다면
둘은 Heap에 같은 곳을 보게되므로 == 연산자를 통해 비교하면 true가 나온다.
여기서
f6 += Test.Method2; 를 하게 된다면
f6 = f6 + Test.Method2; 와 같은 코드가 아니라
f6 = new FUNC( ... ) 와 같은 코드가 되어서 f7은 변하지 않는다.
그리고 둘은 다른 객체가 된다 (==연산자 시 false)
2. Delegate Chain 리턴 값
using System;
class Test {
public static int Method1() {
Console.WriteLine("Method1");
return 1;
}
public static int Method2() {
Console.WriteLine("Method2");
return 2;
}
public static int Method3() {
Console.WriteLine("Method3");
return 3;
}
public static int Method4() {
Console.WriteLine("Method4");
return 4;
}
}
delegate int FUNC();
class Program {
public static void Main() {
FUNC uni = Test.Method1;
int ret1 = uni();
Console.WriteLine(ret1); // 1
FUNC multi = Test.Method1;
multi += Test.Method2;
multi += Test.Method3;
multi += Test.Method4;
int ret2 = multi();
Console.WriteLine(ret2); // 4
}
}
실행 결과
Method1
1
Method1
Method2
Method3
Method4
4
multi는 메소드4개를 가지고 있지만 반환값은 마지막 메소드 하나이다.
하다보면 모든 메소드의 반환값을 받고 싶을 때도 있을텐데
GetInvocationList() 라는 메소드를 사용해서 얻을 수 있다.
메소드를 사용하면 모든 반환값이 배열형태로 반환된다.
Delegate타입의 배열을 만들어 받고
foreach문을 통해 하나씩 돌려주면 된다.
using System;
class Test {
public static int Method1() {
Console.WriteLine("Method1");
return 1;
}
public static int Method2() {
Console.WriteLine("Method2");
return 2;
}
public static int Method3() {
Console.WriteLine("Method3");
return 3;
}
public static int Method4() {
Console.WriteLine("Method4");
return 4;
}
}
delegate int FUNC();
class Program {
public static void Main() {
FUNC multi = Test.Method1;
multi += Test.Method2;
multi += Test.Method3;
multi += Test.Method4;
Delegate[] arr = multi.GetInvocationList();
foreach(Delegate d in arr) {
FUNC f = (FUNC)d;
int ret = f();
Console.WriteLine(ret);
}
}
}
실행 결과
Method1
1
Method2
2
Method3
3
Method4
4
① Multicast Delegate의 반환값 얻기
=> GetInvocationList() 사용
728x90
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] Action, Func (0) | 2020.04.16 |
---|---|
[C#] event (0) | 2020.04.08 |
[C#] Delegate Example (0) | 2020.04.06 |
[C#] Delegate (2) (0) | 2020.04.04 |
[C#] Delegate (1) (0) | 2020.03.30 |