VB.NET 같은 경우엔 정수(Integer, Long 같은..)에 문자열을 대입해도 스마트하게 형 변환이 일어납니다. (여기서 말하는 형 변환이라 함은 문자열 값을 정수로 바꾸는 것이 아니라, 숫자에 해당하는 문자를 숫자로 바꾼다고 하는게 맞겠네요)


즉, 이런 코드가 오류 없이 수행되죠.

Dim A As Integer = "34"


반면 C#의 경우는 다릅니다. 문자열 값을 값으로 바꿔주지 않죠. VB.NET을 하다가 C#을 할 때 적응하기가 어려운 경우.. 분명 맞는 코드를 입력했는데 VB.NET과 결과가 다른 경우가 아래의 코드에서 나타나죠.

Int32 A = "34";


이렇게 코딩을 하면 컴파일 오류가 발생하게 됩니다.

코드 CS0029 에 해당하는 오류인 "암시적으로 'int' 형식을 'string' 형식으로 변환할 수 없습니다"

강제 형변환(Casting)을 이용할 경우에도 오류는 마찬가지로 발생합니다.

코드 CS0030 에 해당하는 오류인 "'int' 형식을 'string' 형식으로 변환할 수 없습니다" 라고 말이죠.


그럼 어떻게 문자열을 값으로 바꿀 수 있을까요? 해결법은 매우 간단합니다.

기본 형식에는 모두 Parse 및 TryParse 메서드가 있습니다.

이 메서드는 정적 메서드라서 [형식].Parse, [형식].TryParse 처럼 사용할 수 있습니다.


Parse 및 TryParse 메서드는 인터페이스를 구현하는 메서드가 아니기 때문에 설명을 하나로 통일할 수가 없습니다.

그래서 예제로는 부호 있는 4바이트 정수인 'Int32' 형식으로 설명하도록 하겠습니다.

Int32.Parse 메서드 (MSDN)

Int32.TryParse 메서드 (MSDN)


각 메서드의 정의는 다음과 같습니다.

public static int Parse(String s);
public static bool TryParse(String s, out int result);


Parse 메서드의 경우 문자열을 매개 변수로 받고, 그 문자열을 바로 정수 값으로 변환하게 됩니다.

하지만, 유효하지 않은 문자열인 경우(= 이 말은 숫자로 바꿀 수 없는 문자열이 입력된 경우를 말합니다)에 변환은 완료되지 않고 '입력 문자열의 형식이 잘못되었습니다' 라는 메세지와 함께 System.FormatException 예외를 발생시키게 됩니다.


하지만, TryParse 메서드의 경우는 다릅니다. TryParse 메서드는 문자열과 변환 결과 값이 저장될 정수 변수. 총 두개의 매개 변수를 받습니다. TryParse 메서드의 경우는 변환에 성공했을 경우에 true 를 반환하고 변환에 실패한 경우엔 false 를 반환하기 때문에 예외를 발생시키지 않고, 반환 값을 검사하여 true 일 때에만 값을 가지고 작업을 하면 됩니다.


그러면 Parse 메서드를 굳이 쓸 필요가 있을까요?

일단, 두 메서드의 차이를 보도록 하겠습니다. (차이는 거의 없습니다. 예외를 발생시키느냐 시키지 않느냐의 차이입니다)


Parse 메서드가 내부적으로 호출하는 메서드 (실질적으로 변환을 하는 메서드)

internal unsafe static int ParseInt32(string s, NumberStyles style, NumberFormatInfo info)
{
    byte* stackBuffer = stackalloc byte[((UIntPtr)Number.NumberBuffer.NumberBufferBytes) / 1];
    Number.NumberBuffer numberBuffer = new Number.NumberBuffer(stackBuffer);
    int result = 0;
    Number.StringToNumber(s, style, ref numberBuffer, info, false);
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) {
        if (!Number.HexNumberToInt32(ref numberBuffer, ref result)) {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
    }
    else {
        if (!Number.NumberToInt32(ref numberBuffer, ref result)) {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
    }
    return result;
}


TryParse 메서드가 내부적으로 호출하는 메서드 (실질적으로 변환을 하는 메서드)

internal unsafe static bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result)
{
    byte* stackBuffer = stackalloc byte[((UIntPtr)Number.NumberBuffer.NumberBufferBytes) / 1];
    Number.NumberBuffer numberBuffer = new Number.NumberBuffer(stackBuffer);
    result = 0;
    if (!Number.TryStringToNumber(s, style, ref numberBuffer, info, false)) {
        return false;
    }
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) {
        if (!Number.HexNumberToInt32(ref numberBuffer, ref result)) {
            return false;
        }
    }
    else {
        if (!Number.NumberToInt32(ref numberBuffer, ref result)) {
            return false;
        }
    }
    return true;
}


ParseInt32 메서드의 경우 입력 문자열의 형식이 자료형에 맞지 않을 경우에 예외를 발생시키고, TryParseInt32 메서드의 경우 형식이 자료형에 맞지 않을 경우엔 bool 값을 반환하고 있습니다(=false).


그럼에도 불구하고 Parse 메서드를 사용하는 이유는 정말 간단합니다.

예외 처리가 가능하기 때문입니다.

제가 C#으로 소켓 만들 때 설명드렸듯이, 예외 처리는 프로그램을 더욱 유연하고 오류를 적게 만들 수 있도록 해줍니다.



거두절미하고! VB.NET 에서는 자동으로 해줬던 문자열을 값으로 변환하는 방법은 Parse 및 TryParse 이 두개의 메서드만 알고 있으면 됩니다. 이 메서드는 기본 형식에 대해 사용이 가능합니다.


긴 글 읽어주셔서 감사합니다!


+ Recent posts