본문 바로가기

C# 일기

17. 예외처리(Exception Handling)

코딩하면서, 런타임에러가 발생하지 않았는데도 컴파일중에 에러가 생기는 경우가 있다.

 

IndexOurofRange, FormatException등 신기한 언어들이 코딩중인 나를 괴롭히는 경우가 허다하다.

 

이러한 경우는 처리되지 않은예외를 컴파일러에서 스스로 감지하여 이용자에게 알려주는 것이다.

 

이렇게 예외를 처리하지 않은 채 프로그램을 실행하면, 처리되지 않은 예외를 만나는 순간 프로그램이 다운되기 때문에, 미리 예외를 처리하는 것이 좋다.

 

예외처리를 함으로써, 이용자가 인지하지 못하는 예외가 발생해 프로그램이 다운되는 것을 막을 수 있으며, 어느부분에서 예외가 발생했는지를 인지하고, 유동적으로 디버깅을 할 수 있기 때문이다.

 

예외처리를 하는 방법 역시 다양한데, 먼저는 if 분기문으로 발생가능한 예외를 상정하는 법이다.

 

using System;

namespace Favor
{
   static void Print(int[] arr, int lenghth)
   {
      if(arr.Length>length || length < 0)
      {
         Console.WriteLine("예외 발생. 입력한 index값이 배열의 크기보다 크거나 0보다 작습니다.");
         return;
      }
      
      for(int i = 0; i < index; i++)
         Console.WriteLine(arr[i]);
         
   }
   internal class Program
   {
      static void Main(string[] args)
      {
         int[] arr = new int[4];
         
         Print(arr, 6);
         // 출력값 : 예외 발생. 입력한 index값이 배열의크기보다 크거나 0보다 작습니다. 
      }
   }
}

  

위와 같이 예외가 발생할만한 조건을 미리 상정하고, 예외가 처리될 시 어떤 부분에서 예외가 발생하였는지, 어떤 예외를 처리하지 않았는지 이용자의 입장에서 이해하기 쉽게 처리할 수 있다.

 

그러나 우리는 어떤 조건에서 어떤 예외가 발생했는지를 단번에 파악하기 어려울 수 있다.

 

만약 우리가 예외에 해당되는 조건이 무엇인지를 전부 알고있다면, 예외가 절대 발생하지 않도록 코딩하면 되는데, 우리는 그럴 수 없다.

 

그래서 예외처리를 쉽게하는 방법 중, try catch문이 있다.

 

try catch문은 try 부분에서 예외가 발생하기 전까지 실행할 코드를 입력하고, 예외를 만나면 해당 예외를 catch로 넘긴다

 

try문에서 넘겨받은 예외는 catch문에서 받아, 해당 예외가 발생시 취할 행동을 코딩하면 된다.

 

using System;

namespace Favor
{
   static void Print(int[] arr, int lenghth)
   {
      try
      {
         for(int i = 0; i < index; i++)
            Console.WriteLine(arr[i]);
      }
      catch(IndexOutofRange ex)
      {
         Console.WriteLine(ex.Message);
         Console.WriteLine("배열범위 밖입니다.");
         return;
      }
         
   }
   internal class Program
   {
      static void Main(string[] args)
      {
         int[] arr = new int[4];
         
         Print(arr, 6);
         // 출력값 : 인덱스가 배열 범위를 벗어났습니다.
         //          배열범위 밖입니다. 
      }
   }
}

 

위처럼 배열의 크기가 4인 arr를 인덱스를 나타내는 매개로 6과 함께 Print함수에 넘겼을 때,

 

try를 실행하는  도중, 인덱스 4를 검사하려고 했을 때, 인덱스 3까지밖에 없는 arr 배열의 4번 인덱스를 검사하려고 하여,

 

IndexOutofRange예외를 발견하여, catch문으로 해당 예외를 넘긴 것이다.

 

여기서 catch 괄호 안의 IndexOutofRange ex는 try문에서 던진 예외를 ex라는 매개로 전달받을 것이라는 뜻이다.  

 

이 때, ex.Message라고 하는 것을 볼 수 있는데, 이는 해당 예외가 무엇인지 알려주는 메시지를 담은 문자열 변수로,

 

어떤 예외를 만났는지 알려주는 역할을 한다.

 

그래서 출력값에서, '인덱스가 배열 범위를 벗어났습니다.' 라고 하는 문구가 출력되었다.

 

 

 

 

catch는 try에서 넘겨줄 수 있는 예외 만큼 필요하다.

 

try부에서 상정가능한 예외 상황이 3개라면, 해당 예외상황에 맞는 catch문 3개를 작성해야 한다.

 

 

 

 

 

이 외에도, 발생시 프로그램 구동에 있어 치명적인 작동이 발생할 경우에 대비하여, 예외를 의도적으로 발생시키는 방법도 존재한다.

 

이를 throw라고 하며, 그 에는 아래와 같다.

 


         try
	{
    	   int[] array = { 1, 3, 5, 7, 9 };
    	   int index=Array.IndexOf(array, 8);
    	   if (index < 0)
           	throw new InvalidOperationException();
    	   array[index] = 0;
	}
	catch (InvalidOperationException ex)
	{
    	   Console.WriteLine(ex.Message);
    	   Console.WriteLine("배열에서 원하는 값을 찾지 못함");
	}

 

8이 존재하지 않는 배열 array에서 8이 시작하는 곳의 인덱스를 찾아 0으로 바꾸려는 코드이다.

 

이 경우엔 배열에서 원하는 값을 찾을 수 없을 경우, -1을 반환하기 때문에 -1이 반환되면 InvalidOperationException이라는 예외를 출력하기로 했다.

 

IndexOf에서 -1이 반환되면, InvalidOperationException이라는 예외를 catch에게 던져, 받은 예외를 처리하도록 했다.

 

 

 

'C# 일기' 카테고리의 다른 글

19. 이벤트(Event)  (0) 2024.03.11
18. 대리자 (Delegate)  (0) 2024.03.11
16. 일반화 (Generic <T>)  (0) 2024.03.08
15. 연산자 오버로딩  (0) 2024.03.08
14. Array 클래스  (0) 2024.03.08