9장, 부록 (9-1)
* 제네릭Generic
: 일반 클래스. 형을 매개변수로 범용성있게 표현하는 방법.
: 해당 클래스의 정의 내에서 이용되는 형의 종류가 결정되어 있지 않고 매개변수로 되어 있는 것. 구체적인 형은 객체 생성 시에 지정한다.
복수의 매개변수를 지정하는 것도 가능하다.
class A <T,Z> { public T t; public Z x() { .... } .. A<int,string> a = new A<int,string>(); |
* 델리게이트delegate
: 메소드를 참조하는 형. C언어 함수의 포인터와 원리가 비슷하다.
- 작성 방법
1. 먼저 클래스와 같이 선언한다.
2. 그것을 인스턴스화 하면 delegate가 성립한다.
3. 연결한 메소드를 이용하려면 delegate 이름을 지정한다.
delegate int DelegCalc(int a, int b); class DelegSample { static int multi (int x, int y) { // 메소드의 정의 ... } static void Main() { DelegCalc deleg = new DelegCalc(multi); // deleg = multi;라고 쓸 수도 있음. ... int a = deleg(9, 6); Console.WriteLine(a); } } |
delegate : delegate가 참조하는 메소드의 반환 값의 형
int a, int b : delegate가 참조하는 메소드의 인수
deleg : delegate 변수
- 멀티캐스트
: 참조하는 메소드는 몇 개든 '+'로 추가하거나 '-'로 삭제할 수 있다.
- 이벤트
: 프로그램 안에서 일어나는 현상. 이벤트에 반응하는 메소드를 이벤트 핸들러라 한다.
: C# 언어는 기능이 클래스마다 정리되어 있다. 어딘가에서 일어난 이벤트에 대해 해당 이벤트 핸들러는 별도의 클래스에 들어 있는 것이 일반적이다.
: 이벤트가 일어난 클래스에서 다른 클래스의 메소드를 연결한 delegate를 호출하는 것이 좋다.
: 다만 이 경우, 다른 클래스에서 쉽게 delegate를 호출해 버린다. 그래서 이벤트 핸들러의 등록과 삭제만 가능한, delegate의 속성 같은 구조가 있는데 이것이 C# 언어의 이벤트이다.
이벤트를 선언하려면 delegate선언에 event를 붙인다.
이렇게 하면 자체의 클래스에서는 호출할 수 있지만 다른 클래스에선 '+='에 의한 등록과 '-='에 의한 삭제가 불가능하다.
이벤트의 선언부를 아래와 같이 수정하면 대입/참조의 동작을 사용자 정의할 수 있다. get/set이 아니다.
class EventClass { DelegEvent deleg; public event DelegEvent delegevent { add => deleg += value; remove => deleg -= value; } ... |
- 람다식
: 이걸 사용하면 메소드를 정의하지 않고 바로 메소드의 내용을 기술할 수 있다.
= delegate변수를 더 쉽게 준비할 수 있다.
람다식은 인수형과 return을 생략하고
n => n * n * n;
으로 기술할 수도 있다.
- Func<T, TResult> 라는 제네릭 형식의 델리게이트를 사용하면, 위의 델리게이트 정의도 필요 없다.
… Static void Main(string[] args) { Func<int, int> mycalc = (int n) => {return n * n * n;}; Console.WriteLine(mycalc(5)); } |
int : 인수의 형
int : 반환값의 형
(int n) => {return n * n * n;} : 람다식
- 미리 준비된 주요 델리게이트
델리게이트 | 인수 | 반환 값 |
Func<TResult> | 없음 | TResult |
Func<T, TResult> | T | TResult |
Func<T1, T2, TResult> | T1, T2 | TResult |
Action | 없음 | 없음 |
Action<T> | T | 없음 |