C# 일반
Generic을 사용하면 프로그램에서 실제로 사용될 때까지 클래스나 메서드의 프로그래밍 요소에 대한 데이터 유형 사양 작성을 연기할 수 있습니다. 즉, 제네릭을 사용하면 모든 데이터 유형에서 작동할 수 있는 클래스나 메서드를 작성할 수 있습니다.
데이터 유형의 대체 매개변수를 통해 클래스나 메소드의 사양을 작성할 수 있습니다. 컴파일러는 클래스 생성자 또는 메서드에 대한 함수 호출을 발견하면 지정된 데이터 유형을 처리하는 코드를 생성합니다. 다음의 간단한 예는 이 개념을 이해하는 데 도움이 될 것입니다.
using System; using System.Collections.Generic; namespace GenericApplication { public class MyGenericArray<T> { private T[] array; public MyGenericArray(int size) { array = new T[size + 1]; } public T getItem(int index) { return array[index]; } public void setItem(int index, T value) { array[index] = value; } } class Tester { static void Main(string[] args) { // 声明一个整型数组 MyGenericArray<int> intArray = new MyGenericArray<int>(5); // 设置值 for (int c = 0; c < 5; c++) { intArray.setItem(c, c*5); } // 获取值 for (int c = 0; c < 5; c++) { Console.Write(intArray.getItem(c) + " "); } Console.WriteLine(); // 声明一个字符数组 MyGenericArray<char> charArray = new MyGenericArray<char>(5); // 设置值 for (int c = 0; c < 5; c++) { charArray.setItem(c, (char)(c+97)); } // 获取值 for (int c = 0; c < 5; c++) { Console.Write(charArray.getItem(c) + " "); } Console.WriteLine(); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
0 5 10 15 20 a b c d e
Generics의 특징
Generics를 사용하는 것은 프로그램 기능을 향상시키는 기술, 특히 다음 측면에서:
코드 재사용을 극대화하고 유형 안전성을 보호하며 성능을 향상시키는 데 도움이 됩니다.
일반 컬렉션 클래스를 만들 수 있습니다. .NET Framework 클래스 라이브러리에는 System.Collections.Generic 네임스페이스에 몇 가지 새로운 일반 컬렉션 클래스가 포함되어 있습니다. System.Collections의 컬렉션 클래스 대신 이러한 일반 컬렉션 클래스를 사용할 수 있습니다.
자신만의 일반 인터페이스, 일반 클래스, 일반 메서드, 일반 이벤트 및 일반 대리자를 만들 수 있습니다.
일반 클래스가 특정 데이터 유형의 메서드에 액세스하도록 제한할 수 있습니다.
일반 데이터 유형에 사용되는 유형에 대한 정보는 리플렉션을 사용하여 런타임에 얻을 수 있습니다.
Generic 메소드
위의 예에서는 제네릭 클래스를 사용했으며, 타입 매개변수를 통해 제네릭 메소드를 선언할 수 있습니다. 다음 프로그램은 이 개념을 보여줍니다.
using System; using System.Collections.Generic; namespace GenericMethodAppl { class Program { static void Swap<T>(ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; } static void Main(string[] args) { int a, b; char c, d; a = 10; b = 20; c = 'I'; d = 'V'; // 在交换之前显示值 Console.WriteLine("Int values before calling swap:"); Console.WriteLine("a = {0}, b = {1}", a, b); Console.WriteLine("Char values before calling swap:"); Console.WriteLine("c = {0}, d = {1}", c, d); // 调用 swap Swap<int>(ref a, ref b); Swap<char>(ref c, ref d); // 在交换之后显示值 Console.WriteLine("Int values after calling swap:"); Console.WriteLine("a = {0}, b = {1}", a, b); Console.WriteLine("Char values after calling swap:"); Console.WriteLine("c = {0}, d = {1}", c, d); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Int values before calling swap: a = 10, b = 20 Char values before calling swap: c = I, d = V Int values after calling swap: a = 20, b = 10 Char values after calling swap: c = V, d = I
일반 대리자
유형 매개변수를 통해 일반 대리자를 정의할 수 있습니다. 예:
delegate T NumberChanger<T>(T n);
다음 예에서는 대리자의 사용을 보여줍니다.
using System; using System.Collections.Generic; delegate T NumberChanger<T>(T n); namespace GenericDelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { // 创建委托实例 NumberChanger<int> nc1 = new NumberChanger<int>(AddNum); NumberChanger<int> nc2 = new NumberChanger<int>(MultNum); // 使用委托对象调用方法 nc1(25); Console.WriteLine("Value of Num: {0}", getNum()); nc2(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Value of Num: 35 Value of Num: 175