제네릭 컬렉션 (Generic Collection)

2022. 1. 24. 00:00CSharp/Advance

반응형

Generics는 .NET에 형식 매개 변수 개념을 도입하여 클라이언트 코드에서 클래스 또는 메서드를 선언하고 인스턴스화할 때까지 하나 이상의 형식 지정을 연기하는 클래스 및 메서드를 설계할 수 있도록 한다. 

 

.NET 의 제네릭 컬렉션 

Dictionary<TKey,TValue> : 키별로 빠르게 조회할 수 있도록 항목을 키/값 쌍으로 저장

 

List<T> : 인덱스별로 항목 액세스

 

Queue<T> : FIFO(선입 선출) 방식으로 항목 사용

 

Stack<T> :  LIFO(후입 선출) 방식으로 데이터 사용

 

LinkedList<T> : 순서대로 항목 액세스

 

ObservableCollection<T> : 항목을 컬렉션에 추가하거나 컬렉션에서 제거할 때 알림이 표시됩니다.

 

SortedList<TKey,TValue> : 정렬된 컬렉션

 

HashSet<T> , SortedSet<T> : 수학 함수용 집합

 

대표적으로 많이 사용되는 Array 의 Generic 버전인 List<T> 와 HashTable 의 Generic 버전인 Dictionary<TKey, TValue> 에 대한 사용 방법을 알아보자.

 

Array 의 Generic 버전인 List<T> 사용법

public class GenericList
{
    public class Shape
    {
        protected virtual string GetClassName() => GetType().Name;
        public virtual void PrintDraw() =>Console.WriteLine($"Drawing a {GetClassName()}");           
    }
    public class Circle : Shape { }
    public class Rectangle : Shape { }
    public class Triangle : Shape { }

    public class Test : ITest
    {
        public void Run()
        {
            List<Shape> list = new List<Shape>();
            // List 에  하나씩 입력
            list.Add(new Shape());
            // 상속한 클래스도 입력 가능 
            list.Add(new Circle());

            // 초기화 선언
            List<Shape> subList = new List<Shape>()
            {
                new Rectangle(),
                new Triangle(),
            };

            // addRange
            list.AddRange(subList);

            // print
            Print(list);

            // 삭제
            list.Remove(list[0]);

            Console.WriteLine($"\nlist[0] 삭제뒤에 list 내용\n");
            // print
            Print(list);

            // 찾기
            Console.WriteLine("\ncircle 을 찾습니다.\n");
            var item = list.Find(shape => shape is Circle);
            if(item != null)
                Console.WriteLine("circle 을 찾았습니다.");
            item?.PrintDraw();
        }

        private void Print(List<Shape> list)
        {
            foreach (var item in list) item.PrintDraw();
        }
    }
}

// output
Drawing a Shape
Drawing a Circle
Drawing a Rectangle
Drawing a Triangle

list[0] 삭제뒤에 list 내용

Drawing a Circle
Drawing a Rectangle
Drawing a Triangle

circle 을 찾습니다.

circle 을 찾았습니다.
Drawing a Circle

 

HashTable 의 Generic 버전인 Dictionary<TKey, TValue> 사용법

public class Shape
{
    protected virtual string GetClassName() => GetType().Name;
    public virtual void PrintDraw() =>Console.WriteLine($"Drawing a {GetClassName()}");           
}
public class Circle : Shape { }
public class Rectangle : Shape { }
public class Triangle : Shape { }

public class Test : ITest
{
    public void Run()
    {
        Dictionary<string, Shape> dic = new Dictionary<string, Shape>();
        // dic 에  하나씩 입력
        Shape newItem = new Shape();
        dic.Add(newItem.GetType().Name, newItem);

        newItem = new Circle();
        // 상속한 클래스도 입력 가능 
        dic.Add(newItem.GetType().Name, newItem);

        // 초기화 선언
        Dictionary<string, Shape> subList = new Dictionary<string, Shape>()
        {
            { typeof(Rectangle).Name, new Rectangle() },
            { typeof(Triangle).Name, new Triangle() },
        };

        // addRange 는 dictionary 에는 없다.
        // dic.AddRange(subList);
        // 그래서 확장 메소드중 concat 를 이용한다. (linq)
        // 실제로 c# 에서 Linq 를 제외하면 coding 이 상당히 힘들어 지게 된다.
        dic = dic.Concat(subList).ToDictionary(d=>d.Key, d=>d.Value);
        // print
        Print(dic);
        // 삭제
        dic.Remove(dic.FirstOrDefault().Key);
        Console.WriteLine($"\ndic.first 삭제 후에 dic 내용\n");
        // print
        Print(dic);
        // 찾기
        Console.WriteLine("\ncircle 을 찾습니다.\n");
        var key = typeof(Circle).Name;
        if (dic.ContainsKey(key))
        {
            var item = dic[key];
            if (item != null)
                Console.WriteLine("circle 을 찾았습니다.");
            item?.PrintDraw();
        } else
        {
            Console.WriteLine("circle 을 찾지 못했습니다.");
        }
    }

    private void Print(IDictionary<string,Shape> list)
    {
        foreach (var item in list) item.Value.PrintDraw();
    }
}

 

관련영상

https://youtu.be/Iv3AnKaHaK0

 

반응형

'CSharp > Advance' 카테고리의 다른 글

제네릭 메서드 (Generic Method)  (0) 2022.01.26
제네릭 클래스 (Generic class)  (0) 2022.01.25
Record  (0) 2022.01.21
Lambda advanced  (0) 2022.01.20
Action, Func, Lambda  (0) 2022.01.19