대리자 선언
delegate int MyDelegate(int a, int b);
대리자는 메서드를 대신하여 호출하는 기법이다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs26_delegate
{
// 대리자 사용하겠다는 선언
delegate int CalcDelegate(int a, int b);
delegate int Compare(int a, int b); // a와 b중에서 뭐가 큰지(작은지) 비교 대리자
#region <대리자 기본>
class Calc
{
public int Plus(int a, int b)
{
return a + b;
}
// static이 붙으면 무조건 실행될 때 최초 메모리에 올라감
// 프로그램 실행중에는 언제든지 접근 가능
public static int Minus(int a, int b)
{
return a - b;
}
}
#endregion
internal class Program
{
//오름차순 비교
static int AscendCompare(int a, int b)
{
if (a > b) return 1;
else if(a == b) return 0;
else return -1;
}
//내림차순 비교
static int DescendCompare(int a, int b)
{
if (a < b) return 1;
else if (a == b) return 0;
else return -1;
}
// 오름차순, 내림차순 정렬 하나의 메소드에서 다 실행 가능
static void BubbleSort(int[] DataSet,Compare comparer)
{
int i = 0, j = 0, temp = 0;
for(i=0;i<DataSet.Length; i++)
{
for (j=0;j<DataSet.Length-(i+1);j++)
{
if (comparer(DataSet[j], DataSet[j+1]) > 0) // 대리자 사용
{
temp = DataSet[j + 1];
DataSet[j+1] = DataSet[j];
DataSet[j] = temp; //Swap
}
}
}
}
static void Main(string[] args)
{
#region < 대리자 기본 예>
// 일반적으로 클래스 사용하는 방법 : 직접호출
Calc normalCalc = new Calc();
int x = 10, y = 15;
int res = normalCalc.Plus(x, y);
Console.WriteLine(res);
Console.WriteLine(normalCalc.Plus(x, y));
// class내 static은 Console.WriteLine(normalCalc.Minus(x, y)); 안 된다
res = Calc.Minus(x, y);
Console.WriteLine(res);
// 대리자를 사용하는 방식 : 대리자가 대신 실행
x = 30; y = 20;
Calc delCalc = new Calc();
CalcDelegate Callback;
Callback = new CalcDelegate(delCalc.Plus);
// Calc.Plus() 대신 호출
int res2 = Callback(x, y);
Console.WriteLine("Delegate사용 : {0}", res2);
Callback = new CalcDelegate(Calc.Minus);
res2 = Callback(x, y);
Console.WriteLine("Delegate사용 : {0}", res2);
#endregion
int[] origin = { 4, 7, 8, 2, 9, 1 };
Console.WriteLine("오름차순 버블정렬");
BubbleSort(origin , new Compare(AscendCompare));
foreach(var item in origin)
{
Console.Write("{0}",item);
}
Console.WriteLine();
Console.WriteLine("내림차순 버블정렬");
BubbleSort(origin, new Compare(DescendCompare));
foreach (var item in origin)
{
Console.Write("{0}", item);
}
Console.WriteLine();
}
}
}
대리자 체인
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs27_delegateChain
{
delegate void ThereIsAFire(string location); // 불났을 때 대신해주는 대리자
delegate int Calc(int a, int b);
delegate string Concatenate(string[] args);
class Sample
{
private int valueA; //멤버변수 -> 외부에서 접근 불가
public int ValueA // 프로퍼티
{
/*get { return valueA;}
set { valueA = value; }*/
get => valueA; // 람다식
set => valueA = value;
}
}
internal class Program
{
#region <소방서>
static void Call119(string location)
{
Console.WriteLine("소방서죠! {0}에 불났어요!!",location);
}
static void ShoutOut(string location)
{
Console.WriteLine("{0}에 불났어요!",location) ;
}
static void Escape(string location)
{
Console.WriteLine("{0}에서 탈출합니다.", location);
}
#endregion
static string ProcConcate(string[] args)
{
string result = string.Empty;
foreach(string s in args)
{
result += s + "/";
}
return result;
}
static void Main(string[] args)
{
#region <대리자 체인>
Console.WriteLine("--기본--");
var loc = "우리집";
Call119(loc);
ShoutOut(loc);
Escape(loc);
// 대리자
Console.WriteLine("\n--대리자(체인 연결)--");
var otherloc = "경찰서";
ThereIsAFire fire = new ThereIsAFire(Call119);
fire += new ThereIsAFire(ShoutOut);
fire += new ThereIsAFire(Escape); // 대리자 메서드 연결(추가)
fire(otherloc);
Console.WriteLine("\n--대리자(체인 끊기)--");
fire -= new ThereIsAFire(Escape); // 대리자 메서드 끊기(삭제)
fire("다른집");
Console.WriteLine();
// 익명함수
Calc plus = delegate (int a, int b)
{
return a + b;
};
Console.WriteLine(plus(6, 7));
Calc minus = (a, b) => { return a - b; };
Console.WriteLine(minus(6, 7));
Calc simpleMinus = (a, b) => a - b; //람다식
#endregion
#region <람다식 사용하기>
Concatenate concat = new Concatenate(ProcConcate);
var result = concat(args);
Console.WriteLine(result);
Console.WriteLine("람다식으로");
Concatenate concat2 = (arr) =>
{
string res = string.Empty;
foreach (string s in args)
{
res += s + "/";
}
return res;
};
Console.WriteLine(concat2(args));
#endregion
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs28_event
{
// delegate가 EventHandler 사용하기 위해서 만들었다고 생각하장
// 이벤트를 사용하려면
// 1. 대리자 생성
delegate void EventHandler(string message);
class CustomNotifier
{
// 2. 이벤트를 준비(대리자를 사용한)
public event EventHandler SomeThingChanged;
public void DoSomeThing(int number)
{
int temp = number % 10;
if (temp != 0 && temp % 3 == 0)
{
// 3. 특별한 이벤트가 발생할 상황에서 이벤트를 수행
SomeThingChanged(string.Format("{0} : odd", number));
}
}
}
internal class Program
{
// 4. 이벤트가 대신 호출할 메소드 구현
static void CustomHandler(string message)
{
Console.WriteLine(message);
}
static void Main(string[] args)
{
CustomNotifier notifier = new CustomNotifier();
// notifier에서 SomeThingChanged이벤트가 발생하면 EventHandler(대리자)에서 CustomHandler 가 대신 이벤트 처리해줌
notifier.SomeThingChanged += new EventHandler(CustomHandler);
for (int i = 0; i <= 30; i++)
{
notifier.DoSomeThing(i);
}
}
}
}