2015년 3월 8일 일요일

뇌자극 C# 5.0 - 11~12강

-일반화 프로그래밍-


11.1 일반화 프로그래밍이란?


특수한 개념으로부터 공통된 개념을 찾아 묶는 것을 "일반화"라고 한다.
일반화 프로그래밍은 데이터 형식을 묶는 것.
기능은 같으나 데이터 형식만 다른 경우 일반화를 시켜서 하나로 묶어서 구현하는 것

11.2 일반화 메소드


일반화 메소드는 이름처럼 데이터 형식을 일반화한 메소드이다.
일반화할 형식이 들어갈 자리에 구체적인 형식의 이름 대신 형식 매개변수가 들어간다.

한정자 반환형식 메소드이름<형식매개 변수> (매개변수목록)
{
  //...
}

예제)

//int 버전
void CopyArray( int[] source, int[] target )
{
   for(int i = 0; i < source.Length; i++ )
        target[i] = source[i];
}

//string 버전
void CopyArray( string[] source, string[] target )
{
   for(int i = 0; i < source.Length; i++ )
        target[i] = source[i];
}

를 아래와 같이 일반화 할 수 있다.

void CopyArray<T> ( T[] source, T[] target )
{
   for(int i = 0; i < source.Length; i++ )
        target[i] = source[i];
}

11.3 일반화 클래스


일반화 클래스는 데이터 형식을 일반화한 클래스.

class 클래스 이름 <형식매개 변수>
{
    //....
}

예제)
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_Generic< T >
{
    private T[] array;
    //...
    public T GetElement(int index){ return array[index]; }
}

Array_Generic 클래스 사용하는 법

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

11.4 형식 매개 변수 제약시키기


일반화 메소드나 일반화 클래스가 입력받는
형식 매개 변수 T는 "모든"데이터 형식을 대신할 수 있다.
특정 조건을 갖춘 형식에만 대응하는 형식 매개 변수가 필요할 때
형식 매개 변수의 조건에 제약을 줄 수 있다.

where 형식매개 변수 : 제약조건

where T : struct  => T는 값 형식이어야 한다.
where T : class  => T는 참조 형식이어야 한다.
where T : new() => T는 반드시 매개 변수가 없는 생성자가 있어야 한다.
where T : 기반_클래스_이름  => T는 기반_클래스의 파생 클래스여야 한다.
where T : 인터페이스_이름  => T는 명시한 인터페이스를 반드시 구현해야 한다.
where T : U  => T는 또 다른 형식 매개 변수 U로부터 상속받은 클래스여야 한다.

11.5 일반화 컬렉션


컬렉션은 object 형식을 기반으로 하고 있기에
모든 형식 데이터를 담을 수 있는 장점이 있다.
하지만 object 형식을 기반으로 하기 있기에 성능의 문제를 가지고 있기도 하다.
컬렉션의 요소에 접근할 때 마다 형식 변환이 일어나야 하기 때문이다.

일반화 컬렉션은 컴파일 할 때 사용할 형식이 결정되기에
쓸데 없는 형식 변환을 일으키지 않아 성능에 문제가 없다.

System.Collections.Generic 네임스페이스에 다양한 컬렉션 클래스를 담고 있다.

List<T>, Queue<T>, Stack<T>, Dictionary<TKey,TValue>

위의 4개 일반화 클래스는 비일반화 클래스와 사용법과 기능이 같다.
단, 형식 매개 변수로 입력한 형식 외에는 입력을 허용하지 않는다.

-예외 처리하기-

12.1 예외에 대하여

예외 처리가 왜 중요하냐 하면, 프로그램이 실행중에 아무런 메세지 없이
그냥 오류가 나서 종료되어 버린다면 아무도 그 프로그램은 사용하지 않을 것이다.
그나마 고객에게 덜 욕먹기(?) 위해서는
무슨 오류가 나서 종료되는지 알려주는 것이 예외처리다.

12.2 try~catch로 예외 받기

예외를 받을 때 아래와 같은 형식으로 하면 된다.
try
{
    //실행하고자 하는 코드
}
catch(예외_객체1)
{
   //예외가 발생했을 때의 처리
}
catch(예외_객체2)
{
   //예외가 발생했을 때의 처리
}

12.3 System.Exception 클래스

try
{
}
catch(IndexOutOfRangeException e)
{
   //...
}
catch(DivideByZeroException e)
{
   //...
}

위와 같은 형식을 하나의 catch 절로 처리 할 수 있다.
try
{
}
catch( Exception e )
{
   //.....
}

Exception 클래스를 무조껀  사용하는 것은 금물이다.
프로그래머가 발생할 것으로 계산한 예외 말고도 다른 예외까지 받아내기에
처리하지 않아야 할 예외까지 처리하는 일은 없도록 해야 한다.

12.4 예외 던지기


try~catch 문으로 예외를 받는다는 것은 어디선가 예외를 던진다는 것이다.
예외를 던지는 법은 throw문을 이용해서 던진다.

try
{
   //...
   throw new Exception("예외를 던집니다.");
}
catch(Exception e)
{
   Console.WriteLine(e.Message);
}

12.5 try~catch 와 finally


try 블록에서 코드를 실행하다가 예외를 던져지면 바로 catch 절로 바로 뛰어 넘어온다.
예외 때문에 try블록 안에 있는 중요한 코드를 미처 실행하지 못하고 예외 처리가 된다.
예외 처리가 되어도 반드시 실행해야 하는 코드는 finally 블록안에 지정하면 된다.

try
{
   //...
   dbconn.Open(); //DB 연결
}
catch(Exception e)
{
   Console.WriteLine(e.Message);
}
finally
{
   dbconn.Close(); //예외처리가 되어도 반드시 db 연결은 끊는다.
}

12.6 사용자 정의 예외 클래스 만들기


Exception 클래스를 상속하면 새로운 예외 클래스를 만들 수 있다.

class MyException : Exception
{
   //...
}


댓글 없음:

댓글 쓰기