준비중입니다....
1. Delegate
-
Delegate 정의
method를 가리킬 수 있는 type. -
Delegate 문법
접근제한자 delegate method의_return_type 식별자(.....method의_parameter목록.....);
int Clean (object);
를 delegate type로 정의하면 delegate int FuncDelegate(Object arg);
와 같다.
delegate object를 생성할 때 delegate에 wrapping되는 method의 이름 또는 anonymous Method를 통해 생성된다. 인스턴스화된 delegate는 object이므로 parameter 또는 property로 할당할 수 있다.
class Test
{
// Create a method for a delegate.
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
}
class Program
{
public delegate void Del(string message);
static void Main(string[] args)
{
Del handler = new Del(Test.DelegateMethod);
//Del handler = Test.DelegateMethod; c# 2.0부터는 Delegate type을 new없이 대입할 수 있는 문법을 제공한다.
// Call the delegate.
handler("Hello World");
}
}
-
Delegate 체인
delegate의 가장 강력한 속성은 여러 method들의 chain을 담을 수 있는 delegate이다. method들의 "chain"은 delegate가 invoke될 때 호출된다. 대부분 .NET language에서 delegate chain은 BCL library의 Delegateclass의 Combine() method에 의해 생성된다. 그러나 C#에서는 +operator가 overload해주기 때문에 delegate chain을 문법적으로 더 깔끔하게 생성할 수 있다. -operator는 delegate chain으로부터 해당 method를 제거한다.
using System;
// Define a custom delegate that has a string parameter and returns void.
delegate void CustomDel(string s);
class TestClass
{
// Define two methods that have the same signature as CustomDel.
static void Hello(string s)
{
System.Console.WriteLine(" Hello, {0}!", s);
}
static void Goodbye(string s)
{
System.Console.WriteLine(" Goodbye, {0}!", s);
}
static void Main()
{
// Declare instances of the custom delegate.
CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;
// In this example, you can omit the custom delegate if you
// want to and use Action<string> instead.
//Action<string> hiDel, byeDel, multiDel, multiMinusHiDel;
// Create the delegate object hiDel that references the
// method Hello.
hiDel = Hello;
// Create the delegate object byeDel that references the
// method Goodbye.
byeDel = Goodbye;
// The two delegates, hiDel and byeDel, are combined to
// form multiDel.
multiDel = hiDel + byeDel;
// Remove hiDel from the multicast delegate, leaving byeDel,
// which calls only the method Goodbye.
multiMinusHiDel = multiDel - hiDel;
Console.WriteLine("Invoking delegate hiDel:");
hiDel("A");
Console.WriteLine("Invoking delegate byeDel:");
byeDel("B");
Console.WriteLine("Invoking delegate multiDel:");
multiDel("C");
Console.WriteLine("Invoking delegate multiMinusHiDel:");
multiMinusHiDel("D");
}
}
/* Output:
Invoking delegate hiDel:
Hello, A!
Invoking delegate byeDel:
Goodbye, B!
Invoking delegate multiDel:
Hello, C!
Goodbye, C!
Invoking delegate multiMinusHiDel:
Goodbye, D!
*/
delegate chain 생성 시 원한다면 Chain()이나 Combine() method를 사용해도 된다. 사실상 +operator를 사용했을 때 C# compiler가 내부적으로 Chain, Combine method를 호출하기 때문이다.
-
Event and Delegates
event와 delegate는 component가 비동기적으로 중요한일이 발생한 client를 알리는 것을 허락한다. delegate가 흥미로운 것은 .NET Framework에서 delegate가 event 배후의 근본적인 architecture이다. class가 event를 노출시킬 때 실제로 delegate callback mechanism을 사용한다. 이다. 더 나아가서 VB.NET 뭉 JScript abstract C# abstraction을 제공하지 않는다. event를 노출시키기 위해서 두가지 concept의 결합을 사용해야 한다. event 개념은 delegate의 asynchronous 속성과 밀접한 관련이 있다. -
Responding to a button click in Visual Basic 6
Private Sub Button1_Click()
MsgBox("Button was clicked.")
End Sub
Button1_Click은 button click event를 다룬다고 해서 event handler라 부른다.
C#에서 event는 event keyword에
2. Event
- Event 정의 event도 간편표기법중의 하나인데, 다음 조건을 만족하는 정형화된 callback 패턴을 구현하려고 할 때 event keyword를 사용하면 코드를 줄일 수 있다.
- class에서 event(callback)을 제공한다.
- 외부에서 자유롭게 해당 event(callback)를 구독하거나 해지하는 것이 가능하다.
- 외부에서 구독/해지는 가능하지만 event발생은 오직 내부에서만 가능하다.
- event(callback)의 첫 번째 인자는 event를 발생시킨 타입의 instance다.
- event(callback)의 두 번째 인자는 해당 event에 속한 의미 있는 값이 제공된다.
-
- Event 사용법
public delegate void PriceChangedDelegate(Object o, PriceEventArgs p);
- Object : delegate의 첫번째 parameter는 event를 발생시킨 object class를 담고 있다.
- System.EvetArgs를 상속받은 클래스 : 두번째 parameter는 event가 전달해야하는 정보를 포함한 class이다.
3. 람다식
- 람다식 용도
-
코드로서의 람다 식
anonymous method의 간편 표기 용도로 사용된다. -
데이터로서의 람다 식 람다 식 자체가 데이터가 되어 구문 분석의 대상이 된다. 이 람다식은 별도로 컴파일 할 수 있으며, 그렇게 되면 method로도 실행할 수 있다.
- 람다식 용법
- 코드로서의 람다 식
Thread thread = new Thread{
delegate(object obj)
{
Console.WriteLine("ThreadFunc in anonymous method called!");
}};
C# compiler는 Thread type의 생성자가 "void (object obj)"형식의 delegate parameter를 하나 받는다는 사실을 알고 있다. 따라서 anonymous method의 syntax를 더욱 단순화해서 다음과 같이 정의할 수 있다.
Thread thread = new Thread{
(obj) =>
{
Console.WriteLine("ThreadFunc in anonymous method called!");
}};
람다식은 약식표현을 하나 더 제공한다. 기본적으로 값이 반환된다는 가정하에 return 문을 생략할 수 있으며, 이 경우 람다 식의 연산자인 "=>" 기호 다음에 오는 중괄호까지 생략한다. 약식표현된 람다 식은 세미콜론(;)을 사용해 여러 줄의 코드를 넣을 수 없다는 제약이 있다.
class Program
{
delegate int MyAdd(int a, int b);
delegate int? MyDivide(int a, int b);
static void Main(string[] args)
{
Thread thread = new Thread((obj) => Console.WriteLine("ThreadFunc in anonymous method called!"));
thread.Start();
MyAdd myFunc = (a, b) => a + b;
Console.WriteLine("10 + 2 == " + myFunc(10, 2));
}
}
다음과 같이 anonymous method를 람다 식으로 간편 표기할 수도 있다.
using System;
class Program
{
delegate int? MyDivide(int a, int b);
static void Main(string[] args)
{
MyDivide myFunc = (a, b) =>
{
if (b == 0)
{
return 0;
}
return a / b;
};
Console.WriteLine("10 / 2 == " + myFunc(10, 2));
Console.WriteLine("10 / 2 == " + myFunc(10, 0));
}
}
-
**람다 식을 위한 전용 delegate : **람다 식은 기존 method와 달리 일회성으로 사용되는 간단한 코드를 표현할 때 사용되는데, 정작 그러한 목적으로 delegate를 일일이 정의해야한다는 불편함이 발생한다. 마이크로소프트에서는 이러한 불편을 덜기 위해 자주 사용되는 delegate형식을 generic의 도움으로 일반화해서 BCL에 Action, Func로 포함시켰다.
// return값이 없는 delegate로 입력될 parameter 1개의 type을 지정
public delegate void Action<T>(T arg);
public delegate void Action<T1, T2>(T arg1, T arg2);
public delegate void Action<T1, T2, T3>(T arg1, T arg2, T arg3);
// return값이 있는 delegate로 TResult 형식 parameter는 반환될 타입을 지정
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T arg1, T arg2);
[생략 : T1 ~ T16까지 Action, Func delegate 정의]
-
collection과 람다 식
yield return/break yield return/break keyword를 사용하면기존의 IEnumerable, IEnumerator interface를 이용해 구현했던 열거 기능을 쉽게 구현할 수 있다.
- 람다식으로 Event를 구현하기
4. 확장 메소드 조사
일반적으로 기존 class를 확장하는 방법으로 상속이 많이 쓰인다. 하지만 sealed class나 class를 상속받아 확장하면 기존 소스코드를 새롭게 상속받은 클래스명으로 바꾸어하는 경우에 상속이 좋은 선택은 아니다.
FirstOrDefault() SingleOrDefault() Where() Select() ** overload 버전 전부다 조사할 필요는 없습니다. 위 메소드의 역할과 간단한 샘플만 조사해주세요.
5. LINQ 기본 문법 정리