|
|
#### 준비중입니다.... |
|
|
\ No newline at end of file |
|
|
#### 준비중입니다....
|
|
|
|
|
|
|
|
|
## **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로 할당할 수 있다.
|
|
|
``` cs
|
|
|
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를 제거한다.
|
|
|
``` cs
|
|
|
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**
|
|
|
``` vb
|
|
|
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를 사용하면 코드를 줄일 수 있다.
|
|
|
|
|
|
1. class에서 event(callback)을 제공한다.
|
|
|
2. 외부에서 자유롭게 해당 event(callback)를 구독하거나 해지하는 것이 가능하다.
|
|
|
3. 외부에서 구독/해지는 가능하지만 event발생은 오직 내부에서만 가능하다.
|
|
|
4. event(callback)의 첫 번째 인자는 event를 발생시킨 타입의 instance다.
|
|
|
5. event(callback)의 두 번째 인자는 해당 event에 속한 의미 있는 값이 제공된다.
|
|
|
|
|
|
|
|
|
* * **Event 사용법**
|
|
|
``` cs
|
|
|
public delegate void PriceChangedDelegate(Object o, PriceEventArgs p);
|
|
|
```
|
|
|
1. Object : delegate의 첫번째 parameter는 event를 발생시킨 object class를 담고 있다.
|
|
|
2. System.EvetArgs를 상속받은 클래스 : 두번째 parameter는 event가 전달해야하는 정보를 포함한 class이다.
|
|
|
|
|
|
## **3. 람다식**
|
|
|
* **람다식 용도**
|
|
|
1. 코드로서의 람다 식
|
|
|
anonymous method의 간편 표기 용도로 사용된다.
|
|
|
|
|
|
2. 데이터로서의 람다 식
|
|
|
람다 식 자체가 데이터가 되어 구문 분석의 대상이 된다. 이 람다식은 별도로 컴파일 할 수 있으며, 그렇게 되면 method로도 실행할 수 있다.
|
|
|
* **람다식 용법**
|
|
|
1. 코드로서의 람다 식
|
|
|
``` cs
|
|
|
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를 더욱 단순화해서 다음과 같이 정의할 수 있다.
|
|
|
``` cs
|
|
|
Thread thread = new Thread{
|
|
|
(obj) =>
|
|
|
{
|
|
|
Console.WriteLine("ThreadFunc in anonymous method called!");
|
|
|
}};
|
|
|
```
|
|
|
람다식은 약식표현을 하나 더 제공한다. 기본적으로 값이 반환된다는 가정하에 return 문을 생략할 수 있으며, 이 경우 람다 식의 연산자인 "=>" 기호 다음에 오는 중괄호까지 생략한다. 약식표현된 람다 식은 세미콜론(;)을 사용해 여러 줄의 코드를 넣을 수 없다는 제약이 있다.
|
|
|
``` cs
|
|
|
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를 람다 식으로 간편 표기할 수도 있다.
|
|
|
|
|
|
``` cs
|
|
|
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 기본 문법 정리**
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
``` |
|
|
\ No newline at end of file |