Generic Class 에 대해 part 1

    class GenericClass<T, G> : GenericBase where T : IComparable
  {
       T _genericVariable;
 
        public GenericClass(T t)
       {
           _genericVariable = t;
       }
   
        class NestedGenericClass
       {
           public NestedGenericClass()
            {
           }
       }
   
        static public void GenericClassUsage()
     {
           GenericClass<string, int> constructedType;
          GenericClass<string, int>.NestedGenericClass nestedGenericClass;
        }
   }

일단 위의 예제는 일반적인 Generic Class 의 사용 예제 입니다.

일반적으로 Generic Class는 일반적인 다른 Class와 동일한 룰이 적용 됩니다. 여기에는 일반적인 Class와 다른 룰 혹은 새로운 룰에 대해서만 적도록 하겠습니다.

일단 새로 들어간 사항인 T,G는 type parameter라고 부릅니다. 사실 T,G 자체는 중요하지 않습니다. 단지 <> 안에 type을 대표하는 parameter를 넣을수 있다는것이 중요합니다. C++의 template을 아시는 분은 쉽게 이해 하시라 생각 됩니다.

그러나 C++와 다른 특이 사항이 하나 있는데, 바로 constraint를 줄수 있다는겁니다. C++ template의 경우, template type에 대한 컴파일 타임 제약 사항을 줄수 없습니다. 무슨 말이냐면, C++ 의 template을 사용할 경우, template에 주는 인자가 어떤한 제약 사항을 가지고 있는지 알수가 없습니다. 하지만 C#의 경우는 명시적으로 type parameter에 줄수 있는 인자를 지정할수 있습니다. where T : IComparable 처럼 T로 지정되는 인수는 반드시 IComparable interface를 implement 해야 한다 이렇게 말이죠. 만약 주어진 인자가 명시적 constraint를 충족 하지 못하면, 컴파일러가 에러로 알려줍니다.

Generic class 안에 nested class가 정의 되어 있는 경우, 이 generic class 하의 모든 nested class들은 자동으로 generic class가 됩니다. 이유는 위의 예처럼 명시적으로 type argument를 주지 않는한 nested class들은 사용될수 없기 때문입니다.

아 일단 더 나아가지 전에 Generic class는 constructed type이라고 부릅니다. List<T> 처럼 type parameter가 있는경우는 open constructed type이라고 부르고 List<int>나 List<List<string>> 같은 경우는 closed constructed type이라고 부릅니다.

Generic class의 identifier는 일반적인 Class의 identifier와 동일하게 취급 됩니다. 무슨 말이냐면

class C {}
class C<V> {} // error, C defined twice
class C<V,G> {} // error, C defined twice

와 같이 동일한 class identifier 'C' 를 여러번 정의 할수 없습니다.

오늘은 여기 까지