제네릭의 장점(C# 프로그래밍 가이드)Benefits of Generics (C# Programming Guide)

제네릭은 형식을 유니버설 기본 형식 Object으로/에서 캐스팅하여 일반화가 수행되는 이전 버전의 공용 언어 런타임 및 C# 언어의 제한 사항에 대한 솔루션을 제공합니다.Generics provide the solution to a limitation in earlier versions of the common language runtime and the C# language in which generalization is accomplished by casting types to and from the universal base type Object. 제네릭 클래스를 만들면 컴파일 시간에 형식이 안전한 컬렉션을 만들 수 있습니다.By creating a generic class, you can create a collection that is type-safe at compile-time.

.NET 클래스 라이브러리의 ArrayList 컬렉션 클래스를 사용하는 간단한 프로그램을 작성하면 제네릭이 아닌 컬렉션 클래스를 사용할 경우의 제한 사항을 보여 줄 수 있습니다.The limitations of using non-generic collection classes can be demonstrated by writing a short program that uses the ArrayList collection class from the .NET class library. ArrayList 클래스의 인스턴스는 모든 참조 또는 값 형식을 저장할 수 있습니다.An instance of the ArrayList class can store any reference or value type.

// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);

System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");

하지만 이 편리함에는 대가가 따릅니다.But this convenience comes at a cost. ArrayList에 추가된 모든 참조 형식이나 값 형식이 암시적으로 Object로 업캐스팅됩니다.Any reference or value type that is added to an ArrayList is implicitly upcast to Object. 항목이 값 형식이면 목록에 추가될 때 boxing하고 검색될 때 unboxing해야 합니다.If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved. 캐스팅과 boxing 및 unboxing 작업은 모두 성능을 저하시키므로 큰 컬렉션을 반복해야 하는 시나리오에서는 boxing 및 unboxing이 큰 영향을 줄 수 있습니다.Both the casting and the boxing and unboxing operations decrease performance; the effect of boxing and unboxing can be very significant in scenarios where you must iterate over large collections.

다른 제한 사항은 컴파일 시간 형식 검사가 없다는 것입니다. ArrayList가 모든 항목을 Object로 캐스팅하기 때문에 컴파일 시간에는 클라이언트 코드에서 다음과 같은 작업을 수행하지 않도록 차단할 방법이 없습니다.The other limitation is lack of compile-time type checking; because an ArrayList casts everything to Object, there is no way at compile-time to prevent client code from doing something such as this:

System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");

int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
    t += x;
}

완벽하게 허용되고, 다른 유형의 컬렉션을 만드는 경우 의도적일 때도 있지만 단일 ArrayList에 문자열과 ints를 함께 사용하면 프로그래밍 오류가 발생할 가능성이 크며 이 오류는 런타임 시까지 검색되지 않습니다.Although perfectly acceptable and sometimes intentional if you are creating a heterogeneous collection, combining strings and ints in a single ArrayList is more likely to be a programming error, and this error will not be detected until runtime.

C# 언어의 버전 1.0 및 1.1에서는 사용자 고유의 형식별 컬렉션을 작성해야만 .NET Framework 기본 클래스 라이브러리 컬렉션 클래스에 일반화된 코드가 포함될 위험을 방지할 수 있습니다.In versions 1.0 and 1.1 of the C# language, you could avoid the dangers of generalized code in the .NET Framework base class library collection classes only by writing your own type specific collections. 물론, 이러한 클래스는 둘 이상의 데이터 형식에 다시 사용할 수 없기 때문에 일반화의 이점이 손실되며 저장할 각 형식에 대한 클래스를 다시 작성해야 합니다.Of course, because such a class is not reusable for more than one data type, you lose the benefits of generalization, and you have to rewrite the class for each type that will be stored.

ArrayList 및 다른 유사한 클래스에 실제로 필요한 것은 클라이언트 코드에서 사용할 특정 데이터 형식을 인스턴스 단위로 지정할 수 있는 방법입니다.What ArrayList and other similar classes really need is a way for client code to specify, on a per-instance basis, the particular data type that they intend to use. 그러면 Object로 업캐스팅할 필요가 없으며 컴파일러가 형식을 검사할 수 있습니다.That would eliminate the need for the upcast to Object and would also make it possible for the compiler to do type checking. 즉, ArrayList에 형식 매개 변수가 필요합니다.In other words, ArrayList needs a type parameter. 제네릭은 바로 이것을 제공합니다.That is exactly what generics provide. 제네릭 List<T> 컬렉션의 System.Collections.Generic 네임스페이스에서 컬렉션에 항목을 추가하는 동일한 작업은 다음과 비슷합니다.In the generic List<T> collection, in the System.Collections.Generic namespace, the same operation of adding items to the collection resembles this:

// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();

// No boxing, no casting:
list1.Add(3);

// Compile-time error:
// list1.Add("It is raining in Redmond.");

클라이언트 코드의 경우 ArrayList에 해당하는 List<T>로 추가된 유일한 구문은 선언 및 인스턴스화의 형식 인수입니다.For client code, the only added syntax with List<T> compared to ArrayList is the type argument in the declaration and instantiation. 코딩이 약간 더 복잡하지만 ArrayList보다 안전할 뿐 아니라 특히 목록 항목이 값 형식인 경우 훨씬 더 빠른 목록을 만들 수 있습니다.In return for this slightly more coding complexity, you can create a list that is not only safer than ArrayList, but also significantly faster, especially when the list items are value types.

참고 항목See Also

System.Collections.Generic
C# 프로그래밍 가이드C# Programming Guide
제네릭 소개Introduction to Generics
boxing 및 unboxingBoxing and Unboxing
제네릭 컬렉션 사용 기준When to Use Generic Collections
컬렉션에 대한 지침Guidelines for Collections