뇌를 자극하는 C# 4.0 프로그래밍/ 일반화 프로그래밍

일반화 프로그래밍이란?

  • 로직은 같지만 데이터 형식만 다른 메서드나 클래스를 일반화 하여 하나로 만드는 것. 중복 코드를 줄인다.

일반화 메소드

// 일반화 메소드 선언 방법
한정자 반환형식 메소드이름 <형식매개변수> (매개변수목록)
{
    // 내부 구현
}

// 일반화 메소드 사용 예시
void CopyArray<T> ( T[] source, T[] target )
{
    for ( int i = 0 ; i < source.Length ; i++ )
    {
        target[i] = source[i];
    }
}

int[] source = { 1, 2, 3, 4, 5 };
int[] target = new int[source.Length];

CopyArray<int>(source, target);

string[] source2 = { "하나", "둘", "셋", "넷", "다섯" };
string[] target2 = new string[source2.Length];

CopyArray<string>(source2, target2);

일반화 클래스

// 일반화 클래스 선언 방법
class 클래스이름 <형식매개변수>
{
    // 내부 구현
}

// 일반화 클래스 사용 예시
class Array_Generic<T>
{
    private T[] array;
    public T GetElement(int index)
    {
        return array[index];
    }
}

Array_Generic<int> intArr = new Array_Generic<int>();
Array_Generic<double> doubleArr = new Array_Generic<double>();

형식 매개 변수 제약시키기

// 형식 매개 변수 제약 시키는 방법
where 형식매개변수 : 제약 조건

// 형식 매개 변수 제약 시키기 예시
clss MyList<T> where T : MyClass
{
    // 내부 구현
}

void CopyArray<T>(T[] source, T[] target) where T : struct
{
    // 내부 구현
}
  • 위와 같이 where절을 추가해 주면 클래스나 메소드에 해당 타입에 대한 제약이 생긴다.
  • where절에 쓸 수 있는 제약 조건은 아래 표와 같다.
제약 설명
where T : struct T는 값 형식이어야 한다.
where T : class T는 참조 형식이어야 한다.
where T : new() T는 매개 변수가 없는 생성자를 포함하여야 한다.
where T : 기반클래스이름 T는 명시한 기반 클래스의 파생 클래스여야 한다.
where T : 인터페이스이름 T는 명시한 인터페이스를 구현해야 한다. 인터페이스는 여러 개를 명시할 수 있다.
where T : U T는 또 다른 형식 매개 변수 U로부터 상속받은 클래스여야 한다.

일반화 컬렉션

  • List<T>, Queue<T>, Stack<T>, Dictionary<TKey, TValue>는 각각 ArrayList, Queue, Stack, Hashtable의 일반화 버전이다.
  • 일반화 컬렉션은 컴파일시 형식이 결정되기 때문에 쓸데 없는 형식 변환이 일어나지 않아 object 형식 기반 컬렉션에 비해 나은 성능을 갖는다. 더불어 잘못된 객체를 담을 위험도 피할 수 있다.
  • (실제 클래스 만드는 예시는 생략)

foreach를 사용할 수 있는 일반화 클래스

  • IEnumerable, IEnumerator 인터페이스를 상속하여 메소드와 프로퍼티를 구현하면 foreach를 이용할 수 있지만, 이 경우 형식 변환이 발생한다는 문제가 생긴다.
  • IEnumerable<T>, IEnumerator<T> 인터페이스를 상속하여 메소드와 프로퍼티를 구현하면 형식 변환으로 인한 성능 저하가 없으면서 foreach 순회가 가능한 클래스를 작성할 수 있다.
  • (실제 객체 만드는 예시는 생략)

IEnumerable<T>의 메소드

메소드 설명
IEnumerator GetEnumerator() IEnumerator 형식의 객체를 반환(IEnumerator로부터 상속받은 메소드)
IEnumerator<T> GetEnumerator() IEnumerator<T> 형식의 객체를 반환

IEnumerator<T>의 메소드와 프로퍼티

메소드 설명
boolean MoveNext() 다음 요소로 이동. 컬렉션의 끝을 지난 경우에는 false, 이동이 성공한 경우에는 true를 반환한다.
void Reset() 컬렉션의 첫 번째 위치의 “앞”으로 이동. 첫 번째 위치가 0번 이라면 Reset()을 호출하면 -1로 이동하게 된다. 첫 번째 위치로의 이동은 MoveNext()를 호출한 다음에 이루어진다.
Object Current { get; } 컬렉션의 현재 요소를 반환한다.(IEnumerator로부터 상속받은 프로퍼티)
T Current { get; } 컬렉션의 현재 요소를 반환한다.
It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기