Lamda식 과 대리자 추가내용

이승한·2023년 7월 11일
0

CSharp

목록 보기
12/25

Lamda식

우리가 코드를 만들다 보면 일일이 확인하는 함수를 만든다거나 찾는 함수를 만들 때가 있는데
이러한 함수들은 찾는것에 종류등에 따라 여러개 만들어야할 수 있는 상황이 생긴다.
그래서 종류에따라 함수들을 만들면 너무 비효율적인데 이러한 상황에서 사용할 수 있는 문법이 Lamda식이다.

간단히 Lamda식을 설명해보자면

일회용 함수를 만드는데 사용하는 문법 ==> 함수를 일일이 만들지않고 빠르게 만드는 방법

코드로 예를 들자면,

1.Item 클래스 존재
1-1. 종류:Weapon,Armor,Amulet,Ring
1-2. 희귀도: Normal,Uncommon,Rare

enum ItemType
{
    Weapon,
    Armor,
    Amulet,
    Ring
}
enum Rarity
{
    Normal,
    Uncommon,
    Rare,
}
class Item
{
    public ItemType ItemType;
    public Rarity Rarity;
}

2.메인함수
2-1.Item의 리스트
2-2.Item의 delegate
2-3.FindItem 함수
2-4.메인함수 익명함수,람다식

static List<Item> _items = new List<Item>();

delegate bool ItemSelector(Item item);

static Item FindItem(ItemSelector selector)
{
	foreach(Item item in _items)
    {
    	if(selector(item))
        	return item;
    }
    return null;
}

static void Main(string[] args)
{
    //Lamda : 일회용 함수를 만드는데 사용하는 문법 ( 함수를 일일이 만들지않고 빠르게 만드는 방법)
    //왜 필요한지 ? 

    _items.Add(new Item() { ItemType = ItemType.Weapon,Rarity = Rarity.Normal });
    _items.Add(new Item() { ItemType = ItemType.Armor, Rarity = Rarity.Uncommon });
    _items.Add(new Item() { ItemType = ItemType.Ring, Rarity = Rarity.Rare });

    Item item = FindItem(IsWeapon);
    // Anonymous Function : 무명,익명 함수
    Item item2 = FindItem(delegate (Item item) { return item.ItemType == ItemType.Weapon; });
    //Lamda식
    Item item3 = FindItem((Item item) => { return item.ItemType == ItemType.Weapon; });

}

또한,일회용 함수도 재사용이 가능하다.

//delegate도 객체를 만들 수 있었다. 객체에 람다식을 넣고 밑에처럼 재사용 하면 된다.
ItemSelector selector = new ItemSelector((Item item) => { return item.ItemType == ItemType.Weapon; });

Item item = Finditem(selector); //재사용

위에 방법처럼 대리자를 이용하여 사용할 인자를 넘겨줄 함수의 형식을 선언해도 되지만 더욱 간편히 일반화하여 사용하는 방법이 있다.

static List<Item> _items = new List<Item>();
//앞으로 반환형식이 1개있고 입력하는 형식1개인 대리자는 모두 MyFunc로 처리
delegate Return MyFunc<T,Return>(T item);
//인자 개수가 다르면 다른버전을 계속 만들면 된다.
delegate Return MyFunc<T1,T2,Return>(T1 t1,T2 t2, item);
static Item FindItem(MyFunc<Item,bool> selector)
{
	foreach(Item item in _items)
    {
    	if(selector(item))
        	return item;
    }
    return null;
}

static void Main(string[] args)
{

    _items.Add(new Item() { ItemType = ItemType.Weapon,Rarity = Rarity.Normal });
    _items.Add(new Item() { ItemType = ItemType.Armor, Rarity = Rarity.Uncommon });
    _items.Add(new Item() { ItemType = ItemType.Ring, Rarity = Rarity.Rare });

    MyFunc<Item,bool> selector = new MyFunc<Item,bool>((Item item) => { return item.ItemType == ItemType.Weapon; });
//위의 코드에서 new를 안써도 괜찮다.
//MyFunc<Item,bool> selector = (Item item) => { return item.ItemType == ItemType.Weapon; }; 

	Item item = Finditem(selector); //재사용

}

맨 위에 ItemSelector처럼 특정 기능만 하는게아니라 MyFunc로 인자에 따른 처리로 만들어두면 일반화하기 쉬운데 이게 C#에서 따로 구현이 되어 있다.

Func 와 Action

static Item FindItem(Func<Item,bool> selector)
{
	foreach(Item item in _items)
    {
    	if(selector(item))
        	return item;
    }
    return null;
}

//Func는 위에 만든 MyFunc와 같은 기능을하는데 T1~T16 버전까지 있고 반환형이 있는 형식
MyFunc<Item,bool> selector = (Item item) => { return item.ItemType == ItemType.Weapon; };

//Action은 void반환 형식의 형식
Action<Item>

정리 : delegate를 직접 선언하지 않아도, 이미 만들어진 기능이 있다.
반환 타입이 있을 경우 Func
반환 타입이 없을 경우 Action

0개의 댓글