2009. 2. 23. 14:54

C# 제네릭

제네릭 클래스 및 메서드를 사용하면 제네릭이 아닌 형식에서는 불가능한 방식으로 재사용성,형식 안전성 및 효율성을 동시에 달성할 수 있습니다. 제네릭은 컬렉션 및 컬렉션을 다루는 메서드에서 가장 일반적으로 사용됩니다. .NET Framework 클래스 라이브러리 버전 2.0에서는 System.Collections.Generic 이라는 새로운 네임스페이스를 제공하며 이 네임스페에스에는 새로운 제네릭 기반 컬렉션 클래스가 여러 개 있습니다.
버전 2.0을 대상으로 하는 모든 응용 프로그램에서는 이전의 ArrayList 같은 제네릭이 아닌 형식 대신 새로운 제네릭 컬레션 클래스를 사용하는 것이 좋습니다.
물론 사용자 고유의 형식 안전적이고 효율적인 일반화 솔루션 및 디자인 패턴을 제공하기 위해 사용자 지정 제네릭 형식 및 메서드를 만들 수 있습니다.

Ex-1) 예제에서는 이해를 돕기 위해 간단한 제네릭 연결 리스트 클래스를 보여 줍니다.
대부분의 경우에는 사용자가 이러한 클래스를 직접 만들기 보다 .NET Framework 클래스 라이브러리에서 제공하는 List<T> 클래스를 사용하는 것이 좋습니다.

목록에 저장되는 항목의 형식을 지정하기 위해 일반적으로는 구체적인 형식이 사용될 여러 위치에 형식 매개 변수 T가 사용되고 있습니다. 구체적으로는 다음과 같이 사용되고 있으니 참고하시기 바랍니다.

AddHead 메서드의 메서드 매개 변수 형식
공용 메서드인 GetNext의 반환 형식 및 중첩 Node 클래스의 Data 속성
중첩 클래스에 있는 전용 멤버 데이터의 형식 

*  주목

중첩 Node 클래스에서도 T를 사용할 수 있다.
GenericList<int>와 같이 GenericList<T>를 구체적 형식을 사용하여 인스턴스화하면 모든 T가 int로 대체됩니다.

Ex-1)

 // type parameter T in angle brackets
public class GenericList<T>
{
    // The nested class is also generic on T
    private class Node
    {
        // T used in non-generic constructor
        public Node(T t)
        {
            next = null;
            data = t;
        }
        private Node next;
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }

        // T as private member data type
        private T data;
        // T as return type of property
        public T Data  
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node head;
    // constructor
    public GenericList() 
    {
        head = null;
    }
    // T as method parameter type:
    public void AddHead(T t) 
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node current = head;
        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

다음 코드 예제에서는 클라이언트 코드에서 제네릭 GenericList<T> 클래스를 사용하여 정수 목록을 만드는 방법을 보여 줍니다.
형식 매개 변수를 변경하는 간단한 방법으로 아래 코드를 문자열이나 기타 사용자 지정 형식의 목록을 만들도록 쉽게 변경할 수 있습니다. 

class TestGenericList
{
    static void Main()
    {
        // int is the type argument
        GenericList<int> list = new GenericList<int>();
        for (int x = 0; x < 10; x++)
        {
            list.AddHead(x);
        }

        foreach (int i in list)
        {
            System.Console.Write(i + " ");
        }
        System.Console.WriteLine("\nDone");
    }
}

제네릭 - 장점 : 제네릭 기능을 사용하면 제네릭 클래스나 메서드에 의해 사용되는 특정 형식을 지정할 수 있으므로 형식 안전성에 대한 작업을 컴파일러에서 담당하게 됩니다. 컴파일 타임에 형식 안전성이 적용되므로 올바른 데이터 형식을 테스트하기 위해 코드를 작성할 필요가 없습니다. 형식 캐스팅의 필요성과 런타임 오류의 가능성이 줄어듭니다.
제네릭은 여러 구현의 오버헤드 없이 형식 안전성을 제공합니다. 예를 들어, 다음 변수 선언과 함께 연결된 문자열 목록을 만들 수 있습니다. 

C#

LinkedList<string> llist = new LinkedList<string>();

기본 형식에서 상속하고 멤버를 재정의하지 않아도 됩니다. 연결된 목록은 바로 사용할 수 있습니다.
.NET Framework에서 제공하는 제네릭 컬렉션 형식은 System.Collections.Generic 및  system.Collections.ObjectModel을 참조하시면 됩니다.
형식 안전성 외에, 일반적으로 제네릭 컬렉션 형식은 값 형식을 boxing하지 않아도 되므로 값 형식을 효율적으로 저장하고 조작할 수 있습니다.


출처 >> 데브피아 강도욱
       >>http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNo=8&no=1357&ref=1357