C# Generic & 자료구조

선비Sunbei·2023년 1월 10일
0

C#

목록 보기
9/18
post-thumbnail

Generic

using System;

namespace Study17
{
    class Program
    {
        abstract class Base { 
            public abstract void act();
        }
        class Child1 : Base { 
            public override void act()
            {
                Console.WriteLine("싸우는 중");
            }
        }
        class Child2 : Base { 
            public override void act()
            {
                Console.WriteLine("행동1 중");
            }
        }

        class Teacher<T> where T : Base {

            private T t;

            public Teacher(T t){
                this.t = t;
            }
            public void act()
            {
                t.act();
            }
        }

        static void Main(string[] args)
        {
            Teacher<Base> t1 = new Teacher<Base>(new Child1());
            Teacher<Child2> t2 = new Teacher<Child2>(new Child2());
        }
    }
}

다음과 같이 '특정 클래스'에 대해서 '작용하는 클래스'를 만든다고 생각해보자. 만약 '특정 클래스'가 여러개라면 우리는 '작용하는 클래스'를 여러개를 만들어야 할 것이다.
이를 더 효과적으로 사용하기 위해서 우리는 Generic을 쓴다.
사용방법은 다음과 같다.

class 'ClassName'<T> { }
ClassName<int> className = new ClassName<int>;

클래스의 이름 옆에 <>를 쓰고 가운데에 사용할 이름을 쓰면 된다. (꼭 T가 아니어도 된다.)
이렇게 만든다면 우리가 인스턴스를 생성할 때 T부분에 원하는 클래스를 작성하면 된다.

            Teacher<Base> t1 = new Teacher<Base>(new Child1());
           Teacher<Child2> t2 = new Teacher<Child2>(new Child2());

해당 코드를 보면 첫번째 줄은 Base에 대한 T가 되고, 2번째 줄의 경우 Child2에 대한 T가 된다.
만약에 우리가 T에 대한 제한을 두고 싶다면 어떻게 해야할까??
그럴때는 where을 작성하면 된다.

class 'ClassName' where T : 조건{}
where에 대한 제약 조건은 다음 사이트에서 확인이 가능하다.
https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

그렇다면 항상 Generic은 클래스에서만 쓸 수 있느냐? 그것은 아니다.
Generic은 함수에서도 사용이 가능한 방식이다.

using System;

namespace Study18
{
  class Program
  {
      static void Swap<T>(ref T ob1, ref T ob2) where T : struct
      {
          T tmp;
          tmp = ob1;
          ob1 = ob2;
          ob2 = tmp;
      }

      static void Main(string[] args)
      {
          int a = 2;
          int b = 3;
          Swap<int>(ref a, ref b);
          Console.WriteLine($"a:{a},b:{b}");
      }
  }
}

where 절의 struct는 클래스가 아닌 값 형식만 가능하다는 것을 의미한다.

자료구조

C#의 자료구조는 Generic버전과 미사용 버전으로 자료구조가 나뉘어져있다.

GenericGeneric X용도
Dictionary<TKey,TValue>HashtableKey로 빠르게 조회 후 Value 반환
List<T>Array, ArrayList데이터가 저장된 인덱스에 빠르게 접근 가능
Queue<T>QueueFIFO(선입 선출) 방식
Stack<T>StackLIFO(후입 선출) 방식
SortedList<Tkey,Tvalue>SortedList입력된 순서와 관계없이 Key값으로 정렬
LinkedList<T>X데이터 등록, 삭제가 빈번하게 일어날 경우 사용
ObservableCollection<T>X목록에 데이터를 넣거나 뺄 때 알림을 표시해준다.
HashSet<T>, SortedSet<T>X중복된 데이터를 저장하지 않을 때

Generic을 사용하지 않는 버전의 경우 데이터형을 어떻게 알고 저장하나 의문이 들 수 있다. 정답은 Object이다. Object형식으로 저장하기 때문에 빼올 경우 원하는 자료형으로 형변환을 시켜줘야 한다. 여기서 형변환을 시키는게 비용이 있다보니 일반적으로 Generic 자료구조를 사용한다.

0개의 댓글