1. Delegate
Delegate 정의
***델리게이트(Delegate)***는 대리자로 해석되며, 메서드를 가리킬 수 있는 타입으로 메서드를 대신 실행해주는 역할을 한다.
delegate
예약어를 사용하여 타입을 선언한다.
Delegate 문법
public delegate int CalcDelegate(int x, int y);
// 대상 메서드의 반환 타입 및 매개변수 목록과 일치하는 델리게이트 타입을 정의
Delegate 속성
- Delegate는 C++의 함수 포인터와 유사하지만 형식이 안전(type-safety)하다.
- Delegate를 통해 메서드를 매개 변수로 전달할 수 있다.
- Delegate를 사용하여 콜백 메서드를 정의할 수 있다.
- 여러 Delegate를 연결할 수 있습니다. 예를 들어 단일 이벤트에 대해 여러 메서드를 호출할 수 있다.
- 메서드와 Delegate 형식이 정확히 일치할 필요는 없다.
형식 안전성(type-safety) : 어떠한 연산이 예측 불가능한 결과는 내지 않는 것. 형식 안전성이 보장되지 않는 언어는 예측 불가능한 결과를 내게 된다.
Delegate 체인
Delegate를 여러개 연결해서 사용하는 방식이다. 연결된 Delegate는 내부 리스트에 저장되며 차례대로 호출되고 예외 발생시 중단된다.
class Program
{
// Delegate 타입 선언
delegate void ClacDelegate(int x, int y);
static void Add(int x, int y) { Console.WriteLine(x + y); }
static void Subtract(int x, int y) { Console.WriteLine(x - y); }
static void Multiply(int x, int y) { Console.WriteLine(x * y); }
static void Divide(int x, int y) { Console.WriteLine(x / y); }
static void Main(string[] args)
{
ClacDelegate calc = Add;
calc(10, 5); // 15
calc += Subtract;
calc += Multiply;
calc += Divide;
calc(10, 5); // 15 5 50 2
calc -= Subtract;
calc(10, 5); // 15 50 2
}
}
2. Event
Event 정의
event
는 정형화된 콜백 패턴 구현을 위해 사용되는 delegate의 간편 표기법이다.
기존 delegate로도 동일하게 구현할 수 있지만, event 예약어를 사용하면 코드를 줄일 수 있다.
또한 event를 이용해 외부 구독자(Subscriber)에 의해 delegate에 새롭게 할당하는 것을 제한하고, 직접적인 delegate 호출을 제한하고 있다.
이는 개발자의 실수를 방지하고, delegate 포함하는 클래스를 통해 delegate를 호출하므로써 외부 클래스가 이벤트를 발생시키는 것을 방지할 수 있다.
Event 문법
public event EventHandler onChange;
// 클래스의 멤버로 정의.
Event 사용법
delegate void eventDelegate();
class EventTest
{
public event eventDelegate clickEvent;
public void buttonClick() { clickEvent(); }
}
class Program
{
static void Click()
{
Console.WriteLine("클릭");
}
static void Main(string[] args)
{
EventTest eventTest = new EventTest();
eventTest.clickEvent += new eventDelegate(Program.Click);
eventTest.buttonClick();
// 아래 코드는 모두 컴파일 에러
// delegate에 할당되는 것을 제한
// eventTest.clickEvent = new eventDelegate(Program.Click);
// 직접적인 delegate 호출하는것을 제한
// eventTest.clickEvent();
}
}
3. 람다식
***람다 식(Lambda Expression)***은 람다 대수(축약 함수)의 형식을 C#에서 구현한 문법이다.
람다식 용도
익명 메서드의 간편 표기와, Expression Tree를 이용한 구문 분석 용도로 사용된다.
람다식 용법
// 익명 메서드
Thread thread1 = new Thread( delegate (object ojb) { Console.WriteLine("ThreadFunc in anonymous method called!"); });
// 람다 식
Thread thread2 = new Thread( (obj) => { Console.WriteLine("ThreadFunc in anonymous method called!"); });
// 람다 식 약식 표현 (괄호 생략)
Thread thread3 = new Thread( (obj) => Console.WriteLine("ThreadFunc in anonymous method called!") );
// 컬렉션과 람다 식
List<int> list = new List<int> { 3, 1, 4, 5, 2 };
list.ForEach((elem) => { Console.WriteLine(elem + " * 2 == " + (elem * 2)); });
// IEnumerable 타입의 확장 메서드를 이용한 조건 카운팅
int count = list.Count((elem) => elem > 3);
람다식으로 Event를 구현하기
delegate void eventDelegate();
class EventTest
{
public event eventDelegate clickEvent;
public void buttonClick() { clickEvent(); }
}
class Program
{
static void Click()
{
Console.WriteLine("클릭");
}
static void Main(string[] args)
{
EventTest eventTest = new EventTest();
eventTest.clickEvent += () => { Console.WriteLine("클릭"); };
eventTest.buttonClick();
}
}
4. 확장 메소드 조사
FirstOrDefault()
조건에 맞는 데이터중 첫번째 행을 반환한다. NULL 반환에 대한 처리해주어야 한다.
List<int> months = new List<int> { };
// Setting the default value to 1 after the query.
int firstMonth1 = months.FirstOrDefault();
if (firstMonth1 == 0)
{
firstMonth1 = 1;
}
Console.WriteLine("The value of the firstMonth1 variable is {0}", firstMonth1);
Where()
특정 조건을 만족하는 요소를 IEnumerable로 열거형을 반환한다.
List<int> list = new List<int> { 3, 1, 4, 5, 2 };
IEnumerable<int> enumList = list.Where((elem) => elem % 2 == 0);
Array.ForEach(enumList.ToArray(), (elem) => { Console.WriteLine(elem); });
Select()
특정 요소를 IEnumerable로 열거형을 반환한다. 개별 요소를 다른 타입으로 변활할 때 사용할 수 있다.
List<int> list = new List<int> { 3, 1, 4, 5, 2 };
IEnumerable<double> enumList = list.Select((elem) => (double)elem);
Array.ForEach(enumList.ToArray(), (elem) => { Console.WriteLine(elem); });
#5. LINQ 기본 문법 정리
Delegate 체인 http://www.csharpstudy.com/DevNote/Article/15