일반화 프로그래밍 (Generic Programming)
- 클래스 또는 메소드를 정의 할 때, 내부에 사용되는 데이터 형식(Data Type)에 식별자를 지정
- 보통 식별자로 “T” 를 많이 사용
- 식별자에 원하는 데이터 형식을 할당하여 해당 클래스 또는 메소드 사용
- 매개변수의 데이터형식이 다른 오버로딩 메소드들을 효과적으로 일반화
- 예를 들어, int 형 배열을 복사하는 메소드(왼쪽)와 string 형 배열을 복사하는 메소드(오른쪽)
- Int 형과 string 형을 포함해 31가지 데이터형식으로 오버로딩 메소드 작성해야 할 수도 있음
- 일반화 프로그래밍은 데이터형식을 일반화하여 효율적으로 메소드 정의
일반화 메소드/클래스
일반화 메소드
- 매개변수의 데이터형식을 일반화하여 정의한 메소드
- 메소드 이름 뒤에 꺽은 괄호 <> 안에 "T" 를 넣어주면, "T"는 형식 매개변수가 됨
using System;
namespace CopyingArray
{
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[] 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[] source2 = { "하나", "둘", "셋", "넷", "다섯" };
string[] target2 = new string[source2.Length];
CopyArray<string>(source2, target2);
foreach (string element in target2)
Console.WriteLine(element);
}
}
}
일반화 클래스
- 멤버의 데이터형식을 일반화하여 정의한 클래스
- 클래스 이름 뒤에 꺽은 괄호 <> 안에 "T" 를 넣어주면, "T"는 형식 매개변수가 됨
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]);
}
}
}
일반화 클래스 : 두 개 이상의 형식 매개변수
- 일반화 프로그래밍에서 형식 매개변수는 두 개이상으로 사용 가능
using System;
namespace GenericClass
{
class Wanted<T, U> // 두개의 형식매개변수 T, U
{
public T Value1;
public U Value2;
public Wanted(T _value1, U _value2)
{
this.Value1 = _value1;
this.Value2 = _value2;
}
}
class MainApp
{
static void Main(string[] args)
{
Wanted<int, string> wanted = new Wanted<int, string>(1234, "String");
Console.WriteLine($"Value1: {wanted.Value1}, Value2: {wanted.Value2}");
}
}
}
형식 매개변수의 제약
형식 매개변수 제약시키기 : where 키워드
- 특정 조건을 갖춘 형식에만 대응하는 형식 매개변수를 사용하도록 제약
- 메소드 또는 클래스에 where 키워드와 함께 제약조건을 나타냄
형식 매개변수 제약시키기 사용 예제
- 형식 매개변수는 값 형식으로 제약
- 두 개 이상의 형식 매개변수 제약
- 기본 생성자를 가진 어떤 클래스의 객체라도 생성
- 특정 클래스로부터 상속 받은 형식 매개변수 U 사용
형식 매개변수 제약시키기 : 예제 코드
using System;
namespace ConstraintsOnTypeParameters
{ //일반화 클래스 정의
class StructArray<T> where T : struct
{
public T[] Array { get; set; }
public StructArray(int size)
{
Array = new T[size];
}
}
class RefArray<T> where T : class
{
public T[] Array { get; set; }
public RefArray(int size)
{
Array = new T[size];
}
}
class Base { }
class Derived : Base { }
class BaseArray<U> where U : Base
{
public U[] Array { get; set; }
public BaseArray(int size)
{
Array = new U[size];
}
public void CopyyArray<T>(T[] Target) where T : U //T는 상위 형식매개변수U를 상속받도록 강제
{
Target.CopyTo(Array, 0);
}
}
class MainApp
{ //일반화 클래스 인스턴스 생성 및 값 할당
public static T CreateInstance<T>() where T : new()
{
return new T();
}
static void Main(string[] args)
{
StructArray<int> a = new StructArray<int>(3);
a.Array[0] = 0;
a.Array[1] = 1;
a.Array[2] = 2;
RefArray<StructArray<double>> b = new RefArray<StructArray<double>>(3);
b.Array[0] = new StructArray<double>(5);
b.Array[1] = new StructArray<double>(10);
b.Array[2] = new StructArray<double>(1005);
BaseArray<Base> c = new BaseArray<Base>(3);
c.Array[0] = new Base();
c.Array[1] = new Derived();
c.Array[2] = CreateInstance<Base>();
BaseArray<Derived> d = new BaseArray<Derived>(3);
d.Array[0] = new Derived(); // Base 형식은 여기에 할당 할 수 없다.
d.Array[1] = CreateInstance<Derived>();
d.Array[2] = CreateInstance<Derived>();
BaseArray<Derived> e = new BaseArray<Derived>(3);
e.CopyyArray<Derived>(d.Array);
}
}
}
일반화 컬렉션
일반화 컬렉션
- 이전 수업에 배운 기존 컬렉션은 object 형식을 기반
- ArrayList, Queue, Stack … etc
- 모든 데이터형식을 다룰 수 있지만, 컬렉션 요소 접근 때마다 형식변환 수행
- object 형식 기반이기 때문에 태생적인 성능문제를 가지고 있음
- 일반화 컬렉션은 object 형식 기반 컬렉션의 성능문제를 해결
- 형식매개변수를 통해 컴파일할 때 컬렉션에 사용할 형식이 결정됨
- List, Queue, Stack … etc
일반화 컬렉션 : List <T> 예제 코드
- 비일반화 컬렉션 ArrayList와 같은 기능을 하고 사용법도 동일
인스턴스 만들 때 형식 매개 변수 필요. 형식 매개 변수로 입력한 형식 외에는 입력을 허용하지 않음
using System;
using System.Collections.Generic;
namespace UsingGenericList
{
class MainApp
{
static void Main(string[] args)
{
List<int> list = new List<int>(); //int형 데이터를 관리하도록 정의
for (int i = 0; i < 5; i++)
list.Add(i); //i값 추가
foreach (int element in list)
Console.Write($"{element} ");
Console.WriteLine();
list.RemoveAt(2); //index 2에 해당하는 값 삭제
foreach (int element in list)
Console.Write($"{element} ");
Console.WriteLine();
list.Insert(2, 2); //index 2에 2값을 입력
foreach (int element in list)
Console.Write($"{element} ");
Console.WriteLine();
}
}
}
일반화 컬렉션 : Queue <T> 예제 코드
- 비일반화 컬렉션 Queue와 같은 기능을 하고 사용법도 동일
형식 매개 변수를 요구
using System;
using System.Collections.Generic;
namespace UsingGenericQueue
{
class MainApp
{
static void Main(string[] args)
{
Queue<int> queue = new Queue<int>(); //int형 데이터를 관리하도록 정의
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
queue.Enqueue(4);
queue.Enqueue(5);
while (queue.Count > 0)
Console.WriteLine(queue.Dequeue());
}
}
}
일반화 컬렉션 : Stack <T> 예제 코드
- 비일반화 컬렉션 Stack와 같은 기능을 하고 사용법도 동일
형식 매개 변수 요구
using System;
using System.Collections.Generic;
namespace UsingGenericStack
{
class MainApp
{
static void Main(string[] args)
{
Stack<int> stack = new Stack<int>(); //int형 데이터를 관리
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);
while (stack.Count > 0)
Console.WriteLine(stack.Pop());
}
}
}
'전공 > C# 프로그래밍' 카테고리의 다른 글
14강. Winform으로 만드는 사용자 인터페이스 (2) (1) | 2023.06.14 |
---|---|
14강. Winform으로 만드는 사용자 인터페이스 (1) (0) | 2023.06.14 |
12강. 파일 다루기 (2) (0) | 2023.06.03 |
12강. 파일 다루기 (1) (0) | 2023.06.03 |
11강. 인터페이스와 추상 클래스 (3) (0) | 2023.05.27 |
댓글