본문 바로가기
프로그래밍/C#

c# Exception 예외처리

by 뽀도 2017. 6. 14.

C# Exception 예외처리


C#을 포함한 모든 .Net 프로그래밍 언어는 .Net Framework의 Exception 메카니즘에 따라 Exception을 처리한다.

.Net의 System.Exception은 모든 Exception의 Base 클래스이며, 예외 처리는 이 Exception 객체를 기본으로 처리하게 된다.


만약 Exception이 발생하였는데, 이를 프로그램 내에서 처리하지 않으면 이를 Unhandled Exception이라 부른다. 프로그램은 Crash하여 종료하게 된다.


C#에서는 try,catch, finally라는 키워드를 사용하여 Exception을 핸들링하게 되며, 또한 throw라는 c#키워드를 통해 Exception을 만들어 던지거나 혹은 기존 Exception을 다시 던질 수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace csharp_study
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "abc";
            string str2 = "777";
            int num = 0;
            try
            {
                num = int.Parse(str2);
                Console.WriteLine(num); // 실행 성공
                num = int.Parse(str);
                Console.WriteLine(num); // 실행 불가
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex);
                throw;
            }
        }
    }
}
 
cs



결과


str2같은 경우 값이 777이라서 int.parse가 가능하여 에러가 발생하지 않고

Console.log(num);// 실행 성공 부분이 실행됨


하지만 str은 값이 abc인데 abc를 숫자로 변환할 수 없어서 에러가 발생하였고 catch 부분에 Console.WriteLine(ex); 와 throw; 코드에 의해 아래와 같은 로그를 찍음 



처리되지 않은 예외는 throw에서 던지고, system.FormatException 여기는 Console.WriteLine(ex);가 화면에 표시함.



C# try-catch-finally 


try 블럭은 실제 실행하고 싶은 프로그램 명령문들을 갖는 블럭이다.

만약 여기서 어떤 에러가 발생하면, 이는 catch문에서 잡히게 된다. catch문은 모든 Exception을 일괄적으로 잡거나 혹은 특정 Exception을 선별하여 잡을 수 있다.


모든 Exception을 잡고 싶을 때 catch{...}와 같이 하거나 catch (Exception ex) {....} 처럼 모든 Exception의 베이스 클래스인 System.Exception을 잡으면 된다.


특정 Exception을 잡기 위해서는 해당 ExceptionType을 catch하면 된다. 즉 Argument와 관련된 Exception을 잡고 싶으면 catch(ArgumentException ex) {...}와 같이 잡게 된다.


catch블럭은 하나 혹은 여러개 일 수 있다. 여러 catch를 사용하는 이유는 각 Exception 유형에 따라 서로 다른 에러 핸들링을 하기 위함이다.


finally는 Exception이 발생했던 발생하지 않았던 상관없이 마지막에 반드시 실행되는 블럭이다.

예를 들어 try 블럭에서 SQL Connection객체를 만든 경우, finally 블럭에서 Connection 객체의 Close() 메서드를 호출하면, 에러 발생 여부와 상관 없이 항상 Connection객체가 닫히게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace csharp_study
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Try");
            }
            catch(Exception ex)
            {
                Console.WriteLine("catch");
            }
            finally
            {
                Console.WriteLine("Finally");
            }
        }
    }
}
 
cs


결과 

에러는 발생하지 않았고 finally가 마지막으로 실행됨. 



C# throw


try 블럭에서 Exception이 발생하였는데 이를 catch문에서 잡았다면, Exception은 이미 처리된 것으로 간주된다.

때때로 catch문에서 기존의 Exception을 다시 상위 호출자로 보내고 싶을때가 있는데, 이때 throw를 사용한다.


throw문은 크게 2가지로 구별될 수 있다. 즉, (1) throw문 다음에 Exception 객체가 있는 경우와 (2) throw문 다음에 아무것도 없는 경우이다.


throw문 다음에 Exception객체가 있는 경우

throw문 다음에 Exception 객체를 둘 수 있다. 새로운 Exception객체를 만들어 던지기 위해서는 throw new MyException(); 와 같이 C#의 new를 사용하여 새로운 Exception객체를 만든 후 이 객체를 던지면 된다. 만약 기존에 이미 Exception 객체가 있는 경우 throw ex; 와 같이 기존 객체를 사용 할 수 있다.


throw문 다음에 아무것도 없는 경우

throw; 와 같이 뒤에 어떠한 Exception 객체 없이 그냥 throw를 사용할 수 있는데, 이는 catch문에서 잡힌 Exception을 그대로 상위 호출 함수에게 전달하는 일을 한다. 즉, 에러를 발생시킨 하위 Call Stack 모두를 상위 호출 함수에 전달하려면 이렇게 throw;만 호출한다. 이와는 대조적으로 throw 뒤에 Exception 객체를 둔 경우는 기존의 하위 콜스택 정보를 잃어 버리고 현재 메서드로부터 시작되는 콜스택을 만들어 보내는 효과가 있어서 디버깅에 필요한 정보를 잃을 수 있다.




출처 : http://www.csharpstudy.com/CSharp/CSharp-exception.aspx

예제 : 직접 만듬 + 본문 예제 참고 

반응형

'프로그래밍 > C#' 카테고리의 다른 글

C# 이벤트  (0) 2017.06.14
C# 네임스페이스  (0) 2017.06.14
[c#] 한국 원화 \ 표시하기.  (1) 2017.01.09
[C#] 접근 제한자, this  (3) 2016.12.26
데이터 형식 범위  (0) 2015.08.19

댓글