일반화 프로그래밍 – 이것이 C# 이다.
C# 은 프로그래머가 작성한 하나의 코드가 여러 가지 데이터 형식에 맞춰 동작할 수 있도록 하는 일반화 프로그래밍을 지원한다.
이는 코드의 생산성을 좌우하는 아주 중요한 방법이다.
일반화 Generalization
: 특수한 개념으로 부터 공통된 개념을 찾아 묶는 것.
C# 은 “ 데이터의 형식 [DataType] ” 으로 일반화를 할 수 있다.
예를 들어 정수형 배열을 복사하는 기능이 필요하여 메소드를 작성하였다.
static void CopyArray( int[] source, int[] target) { for (int i = 0; i < source.Length; i++) { target[i] = source[i]; } }
이번에는 문자열 배열을 복사하는 기능이 필요하다면?
CopyArray() 메소드에 오버로딩을 하면 된다.
static void CopyArray(string[] source, string[] target) { for (int i = 0; i < source.Length; i++) { target[i] = source[i]; } }
하지만 추후에 float 배열을… 또 AClass를 복사해야 한다면? 나중에 BClass?
무수히 많은 오버로딩 메소드가 작성될 것이다.
위의 예들은 매개변수에 입력되는 배열의 형식만 다를 뿐이므로 우리는 일반화 할 수 있다.
위의 예시는 아래와 같이 일반화 될 수 있다.
구체적인 형식의 이름 대신에 T : 형식 매개변수(Type Paramerter) 가 들어간다.
static void CopyArray<T>(T[] source, T[] target) { for (int i = 0; i < source.Length; i++) { target[i] = source[i]; } }
주의할 사항은 컴파일할 떄 T 가 구체적으로 어떤 형식인지 컴퓨터에게 정의해 줘야 한다는 것
배열을 복사하는 메소드의 일반화 예시
using System; namespace ConsoleApplication1 { public class Copyclass { public Copyclass() { } } class MainApp { static void CopyArray<T>(T[] source, T[] target) { for (int i = 0; i < source.Length; i++) { target[i] = source[i]; } } static void Main(string[] args) { // int 형식 int[] source = { 1, 2, 3, 4, 5 }; int[] target = new int[source.Length]; CopyArray<int>(source, target); foreach (int element in target) { Console.WriteLine(element); } // string 형식 string[] source2 = { "하나", "둘", "셋", "넷", "다섯" }; string[] target2 = new string[source2.Length]; CopyArray<string>(source2, target2); foreach (string element in target2) { Console.WriteLine(element); } // Class 형식 Copyclass copyclass1 = new Copyclass(); Copyclass copyclass2 = new Copyclass(); Copyclass[] source3 = { copyclass1, copyclass2 }; Copyclass[] target3 = new Copyclass[source3.Length]; CopyArray<Copyclass>(source3, target3); foreach (Copyclass item in target3) { Console.WriteLine(item.ToString()); } } } }
해당 형식의 배열을 만드는 클래스가 있다.
class Array_Int { private int[] array; public int GetElement(int index) { return array[index]; } } class Array_Double { private double[] array; public double GetElement(int index) { return array[index]; } }
위의 두 클래스는 데이터의 형식만을 제외하고 다른 부분이 같으니 일반화할 수 있다.
class Array_Gereric<T> { private T[] array; public T GetElement(int index) { return array[index]; } }
위의 일반화된 클래스는 아래와 같이 사용 가능하다
Array_Gereric<int> intArr = new Array_Gereric<int>(); Array_Gereric<double> doubleArr = new Array_Gereric<double>();
클래스 일반화 예시
using System; namespace Generic { class MyList<T> { private T[] array; public MyList() { array = new T[3]; } public T this[int index] { get { return array[index]; } set { if (index >= array.Length) { Array.Resize<T>(ref array, index + 1); Console.WriteLine($"Array Resized : {array.Length}"); } array[index] = value; } } public int Length { get { return array.Length; } } } class MainApp { static void Main(string[] args) { MyList<string> str_list = new MyList<string>(); str_list[0] = "abc"; str_list[1] = "def"; str_list[2] = "ghi"; str_list[3] = "jkl"; str_list[4] = "mno"; for (int i = 0; i < str_list.Length; i++) { Console.WriteLine(str_list[i]); } Console.WriteLine(); MyList<int> int_list = new MyList<int>(); int_list[0] = 0; int_list[1] = 1; int_list[2] = 2; int_list[3] = 3; int_list[4] = 4; for (int i = 0; i < int_list.Length; i++) { Console.WriteLine(int_list[i]); } } } }