'2019/02'에 해당되는 글 3건

Programming/.NET

C# 에서 예외를 처리하는 가장 기본적인 방법은 try ~ catch 구문을 사용하는 것입니다.

 

string s = null;
string a = s.ToString();

 

위 코드는 고의적으로 예외를 발생시키기 위해 작성된 것으로 위와 같이 try catch를 사용하지 않으면 프로그램은 예외를 발생시키고 강제로 종료될 것입니다.

 

try {
    string s = null;
    string a = s.ToString();
} catch (Exception e) {
    Console.WriteLine(e.Message);
}

 

물론 아래와 같이 명시적으로 예외를 발생시키는 것도 가능합니다.

 

try
{
    ApplicationException e = new ApplicationException("오류발생");
    throw e;
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

 

try ~ catch는 해당 구문안에서 예외가 발생하는 경우 처리를 catch하위로 넘기게 됩니다. 이때 예외처리를 담당하게 되는 catch에서는 인자로 Exception 형식의 객체를 받아 이 객체를 통해  Console로 오류메세지를 출력하도록 하고 있습니다.

 

실제 프로그램에서는 초기화 되지 않은 개체의 접근에 대한 System.NullReference(위 예제에서 발생시키는 예외타입에 해당합니다.)나 배열의 잘못된 인덱스지정으로인한 System.IndexOutOfRangeException 등 발생하는 예외의 형식이 다양한데 필요할때 마다 예외형식에 맞는 인스턴스를 활용할 수 있습니다.

 

예제에서 사용된 System.Exception 형식은 가장 최상위의 예외타입에 해당하는 것으로 다른 예외형식들은 모두 System.Exception 으로부터 파생된것이며 예외형식을 직접 구현하는 경우도 System.Exception으로 부터 상속받는 방법으로 예외클래스를 구현해야 합니다. System.Exception를 상속받으면 기본적으로 예외에 대한 설명을 제공하는 Message나 예외를 발생시킨 메서드를 알 수 있도록 하는 StackTrace와 같은 속성을 사용할 수 있습니다.

 

단, StackTrace 속성을 사용하는 경우 정확하게 예외가 발생한 메서드를 파악하려면 해당 프로그램을 Debug로 빌드해야 합니다. Release로 하는 경우 컴파일과정에서 소스코드의 구조가 일부 변경될 수 있기 때문에 StackTrace의 정보는 정확하지 않을 수 있습니다.

 

catch에서 Exception예외를 직접받게되면 try catch안에 발생된 모든 예외를 처리하게 됩니다. 따라서 만약 예외가 발생되는 형태마다 다른 처리를 하고자 한다면 원하는 형식에 맞는 예외타입을 직접 지정해야 합니다.

 

try
{
    string s = "abc";
    string a = s.ToString();

    int[] i = new int[5] { 0, 1, 2, 3, 4 };
    i[5] = 5;
}
catch (NullReferenceException e) //객체참조 오류의 경우 처리부분
{
    Console.WriteLine("참조" + e.Message);
}
catch (IndexOutOfRangeException e) //배열 인덱스 오류의 경우 처리부분
{
    Console.WriteLine("배열" + e.Message);
}
catch (Exception e) {
    Console.WriteLine("그외" + e.Message);
}

 

오류가 발생하든 발생하지 않든 무조건 실행되어야 하는 처리가 필요하다면 finally 를 사용해야 합니다.

 

try
{
    string s = "abc";
    string a = s.ToString();

    int[] i = new int[5] { 0, 1, 2, 3, 4 };
    i[5] = 5;
}
catch (NullReferenceException e) //객체참조 오류의 경우 처리부분
{
    Console.WriteLine("참조" + e.Message);
}
catch (IndexOutOfRangeException e) //배열 인덱스 오류의 경우 처리부분
{
    Console.WriteLine("배열" + e.Message);
}
catch (Exception e)
{
    Console.WriteLine("그외" + e.Message);
}
finally {
    Console.WriteLine("오류발생 유무와 관련없이 무조건 실행");
}

 

지금까지는 이미 정해진 예외(System.NullReferenceException, IndexOutOfRangeException등)를 사용했습니다. 그러나 필요하다면 자신만의 예외타입을 직접 만들 수도 있습니다.

 

class PhoneNumberException : Exception
{
    public PhoneNumberException(string msg) : base(msg) { }
}

 

별도의 예외클래스를 만들고자 하는 경우에는 Exception 으로 부터 클래스를 상속받도록 합니다.

 

try
{
    string s = "010-1234-";

    if (s.Length < 12) {
        PhoneNumberException e = new PhoneNumberException("전화번호 오류입니다.");
        throw e;
    }
}
catch (PhoneNumberException e)
{
    Console.WriteLine(e.Message);
}

 

예제로 만든 예외클래스는 메세지를 전달받아 base 즉, 부모가 되는 Exception에 해당 메세지를 전달하는 단순한 역활만 수행합니다.

 

C# 6.0부터는 이 예외에 조건을 추가할 수 있게 되었습니다.

 

int i = 0;
string input = string.Empty;

try
{
    input = Console.ReadLine();
    i = int.Parse(input);
}
catch (Exception e)
{
    Console.WriteLine($"예외발생!{e.Message}");
}

 

위의 경우 입력값이 변수 i의 타입에 맞지 않으면 예외를 발생시키도록 처리되어 있는데 만약 input이 'abc'일때만 예외를 타도록 하고 싶다면

 

int i = 0;
string input = string.Empty;

try
{
    input = Console.ReadLine();
    i = int.Parse(input);
}
catch (Exception e) when (input.Trim() == "abc")
{
    Console.WriteLine($"abc - 예외발생!{e.Message}");
}
catch (Exception e)
{
    Console.WriteLine($"예외발생!{e.Message}");
}

 

catch뒤에 when을 주고 원하는 조건을 명시하면 됩니다. 이렇게 하면 해당 조건에 부합하는 경우에만 아래 예외로 처리가 이전됩니다. 만약 조건이 복잡하다면 메서드로 분리하여 조건을 지정할 수도 있습니다.

 

static bool check_input(string content)
{
    return (content.Trim() == "abc" ? true : false);
}

 

int i = 0;
string input = string.Empty;

try
{
    input = Console.ReadLine();
    i = int.Parse(input);
}
catch (Exception e) when (check_input(input))
{
    Console.WriteLine($"abc - 예외발생!{e.Message}");
}
catch (Exception e)
{
    Console.WriteLine($"예외발생!{e.Message}");
}

 

또한 catch 나 finally 안에서 await를 활용한 비동기 호출이 가능해졌습니다.

 

try
{
    input = Console.ReadLine();
    i = int.Parse(input);
}
catch (Exception e) when (check_input(input))
{
    Console.WriteLine($"abc - 예외발생!{e.Message}");
}
catch (Exception e)
{
    await Log(e);
}

 

static Task Log(Exception e)
{
    return Task.Factory.StartNew(() => {
        Console.WriteLine(e.Message);
    });
}

'Programming > .NET' 카테고리의 다른 글

[C#] HttpWebRequest / HttpWebResponse / WebClient  (0) 2019.03.12
[C#] 시프트(Shift) 연산자  (0) 2019.03.05
[C#] 예외처리(try ~ catch)  (0) 2019.02.19
[C#] ? / Nullable  (0) 2019.02.12
[C#] partial  (0) 2019.02.07
[C#] 비동기 호출(asynchronous call)  (0) 2019.01.23
0 0
Programming/.NET

ture와 false두가지 값을 갖는 bool형식을 생각해 봅시다. 어느 웹사이트에서 이벤트메일을 수신할 것인지를 지정하는 형식으로 다음과 같이 구현했다면

 

class Member
{
    public bool ReceiveMail
    {
        get;
        set;
    }
}

 

이것은 실제 문제가 될 수 있습니다. 왜냐하면 누군가가 메일수신여부를 아예 설정하지 않았다면 그것은 '네' 또는 '아니오'가 아닌 '미설정'이라는 중간 상태를 가지기 때문입니다. 하지만 bool형식에 중간값은 없으므로 이럴때 Nullable이 사용될 수 있습니다.

 

public Nullable<boolReceiveMail
{
    get;
    set;
}

 

Nullable은 null값을 가지게 하기 위한 것으로 본래는 Nullable<T>로 사용됩니다. 따라서 Nullable<int>와 같은 표현도 가능합니다.

 

Member m = new Member();

if (m.ReceiveMail.HasValue)
    Console.WriteLine(m.ReceiveMail.Value);

 

값을 확인하는 방법은 우선 HasValue속성으로 실제 값을 가지고 있는지를 먼저 확인한 후 Value속성을 통해 값을 가져오면 됩니다.

 

?는 Nullable의 요약된 표현입니다.

 

public boolReceiveMail
{
    get;
    set;
}

 

Nullable과 ?는 완전히 같은 역활을 하며 ?로 하면 실제 컴파일과정에서 코드가 Nullable로 바뀌게 됩니다.

'Programming > .NET' 카테고리의 다른 글

[C#] 시프트(Shift) 연산자  (0) 2019.03.05
[C#] 예외처리(try ~ catch)  (0) 2019.02.19
[C#] ? / Nullable  (0) 2019.02.12
[C#] partial  (0) 2019.02.07
[C#] 비동기 호출(asynchronous call)  (0) 2019.01.23
Debug / Release  (0) 2019.01.15
0 0
Programming/.NET

partial은 하나의 큰 클래스를 2개의 파일이나 부분으로 나누고자 할때 사용됩니다.

 

partial class myValue1
{
    public int i = 100;
}

partial class myValue1
{
    public int j = 200;
}

 

이렇게 하면 물리적으로 2개의 파일로 나누거나 특정한 단위로 하나의 클래스를 나누어 작성할 수도 있습니다.

 

static void Main(string[] args)
{
    myValue1 mv = new myValue1();
    Console.WriteLine(mv.i);
    Console.WriteLine(mv.j);

    Console.Read();
}

 

'Programming > .NET' 카테고리의 다른 글

[C#] 예외처리(try ~ catch)  (0) 2019.02.19
[C#] ? / Nullable  (0) 2019.02.12
[C#] partial  (0) 2019.02.07
[C#] 비동기 호출(asynchronous call)  (0) 2019.01.23
Debug / Release  (0) 2019.01.15
[ASP.NET MVC] Razor  (0) 2019.01.08
0 0
1
블로그 이미지

클리엘