나는 내 기억력을 믿지 않는다

[C#] is 연산자와 ofType메서드 (LINQ)

박도치 2023. 11. 20. 20:57

1.OfType() 메서드

 

OfType()메서드는 특정 데이터를 추출하기 위해 사용되는 메서드이다. List의 타입이 여러가지 일 수 있는데 그 중 하나의 타입값만 추출하고 싶을 경우에 OfType() 메서드를 사용할 수 있다. 

 

아래 예제는 inventory에 있는 LIst<Items> 에 아이템들을 Add하고 있는 코드이다.

 private static void GameItemSetting(Inventory inventory, Shop shop)
 {
     inventory.AddItem(new Weapon("낡은 검1", 3, 1000, 10, false));
     inventory.AddItem(new Weapon("낡은 검2", 3, 1000, 11, false));
     inventory.AddItem(new Weapon("낡은 검3", 3, 1000, 12, false));

     inventory.AddItem(new Armor("낡은 방패", 1, 100, 10, false));
     inventory.AddItem(new HealingPotion("일반 회복 물약", 1, 100, 10, false));
     inventory.AddItem(new HealingPotion("일반 회복 물약", 1, 100, 10, false));
     inventory.AddItem(new ManaPotion("마나 회복 물약", 1, 100, 10, false));
     inventory.AddItem(new ManaPotion("마나 회복 물약", 1, 100, 10, false));

     shop.AddShopItem(new Weapon("황금 검", 2, 300, 20, false));
     shop.AddShopItem(new Armor("황금 방패", 2, 300, 15, false));
     shop.AddShopItem(new HealingPotion("고급 회복 물약", 2, 200, 20, false));
     shop.AddShopItem(new HealingPotion("고오급 회복 물약", 2, 1000000, 20, false));
 }

 

보면 생성시 Weapon도 있고, Armor도 있고 HealingPotion, ManaPotion 여러가지 object가 존재한다. 이 중 하나의 object만을 가지고 오고 싶으면 OfType() 메서드를 이용하면 유용하다.

 

        // 아이템 사용
        public void UseHpPotion()
        {
            // OfType -> LINQ의 지정된 형식으로 형변환이 가능한 요소만을 선택하여 .ToList list에 담은걸 hpPotions에 넣는다.
            var hpPotions = invenItems.OfType<HealingPotion>().ToList();

            foreach (var hpPotion in hpPotions)
            {
                if (hpPotion is HealingPotion)
                {
                    // hpPotion을 사용하고 remove해줌
                    // 하나만 사용해야 하기 때문에 사용시 바로 break로 반복문 탈출
                    hpPotion.Use(player);

                    invenItems.Remove(hpPotion);

                    break;
                }
            }
        }

 

이렇게 위의 invenItems의 HealingPotion만을 가져 와 hpPotions 에 담아줄 수 있다.

 

2. is 연산자

is연산자의 경우도 비슷하지만 질의 구문에는 사용할 수 없다. 즉 true false값을 가질 수 있기 때문에 if구문에 사용할 수 있다.

 

아래 예제는 장비의 중복착용 여부를 막기위해 만든 함수이다.

 

public void EquipmentStatusChange(int num)
{
    //토글
    invenItems[num].IsEquiped = !invenItems[num].IsEquiped;

    // 무기의 중복착용 여부
    if (invenItems[num] is Weapon)
    {
        for (int i = 0; i < invenItems.Count; i++)
        {
            if (i != num && invenItems[i] is Weapon)
            {
                invenItems[i].IsEquiped = false;
            }
        }
    }

    // 방어구의 중복착용 여부 
    else if (invenItems[num] is Armor)
    {
        for (int i = 0; i < invenItems.Count; i++)
        {
            if (i != num && invenItems[i] is Armor)
            {
                invenItems[i].IsEquiped = false;
            }
        }
    }

}

 

item의 배열과 이전 switch구문에서 누른 수를 비교하여 같은 번호면 true 아니면 나머지는 다 false를 줘서 중복착용이 불가능하게 하는 로직이다.

 

if구문에 사용되듯이 OfType()메서드와는 다르게 true false가 가능하며, 내에 있는 object가 어떤걸 가지냐에 따라 다르게끔 해주는 구문이다.

 

 

1. 느낀점

매번 느끼지만 찾아보면 간결하고 좋은 문법들이 너무많다. 역시 구글링도 능력이라고 고생하면서 찾아보면 문제가 해결되지만 진짜 결실을 맺으려면 기록하여 잊지않도록 하는것이 중요하다고 생각된다.

 

이후에도 기억하고 싶은 내용들을 꾸준히 추가하고, 주말에 와서 다시한번 훑어보도록 하자