문자열을 정수로 변환할 때, C# 에서는 주로 Convert.ToInt32()와 int.TryParse()를 사용합니다. 두 방식은 결과는 비슷해 보이지만, 동작 방식과 성능 특성에서 큰 차이를 가집니다.
Convert.ToInt32(string)
int number = Convert.ToInt32("123");
* 문자열을 정수로 변환합니다
* 실패 시 FormatException 예외를 발생시킵니다
try
{
int number = Convert.ToInt32("abc");
Console.WriteLine($"변환 성공: {number}");
}
catch (FormatException)
{
// FormatException 발생
Console.WriteLine("변환 실패: 형식이 올바르지 않습니다");
}
예외는 성능 비용이 크고, 자주 발생할 경우 전체 성능에 영향을 줍니다.
try - catch 문 자체는 정상 동작 시 성능에 거의 영향을 주지 않지만, 실제로 예외가 발생하면 내부적으로 예외 객체 생성, 스택 추적 등 추가 연산이 들어가면서 처리 비용이 커집니다.
그래서 숫자가 확실한 경우가 아닌, 입력 오류가 자주 발생할 수 있는 상황에서는 성능상 불리할 수 있습니다.
int.TryParse(string, out int)
// 결과는 number 에 저장됨
int.TryParse("123", out int number);
* 변환 성공 여부를 bool 로 반환합니다
* 실패해도 예외가 발생하지 않습니다.
* 실패 시 number 는 0 으로 초기화됩니다.
* 반환 결과는 out 변수 number 에 저장됩니다.
* out 변수 number 는 함수 인자에서 바로 선언할 수 있으며, 함수 밖에서 미리 선언하지 않아도 됩니다. (C# 7.0부터 지원)
bool success = int.TryParse("abc", out int number);
if (success)
{
Console.WriteLine($"변환 성공: {number}");
}
else
{
Console.WriteLine("변환 실패"); // number == 0
}
예외 없이 실패를 안전하게 처리할 수 있어, 사용자 입력처럼 불확실한 데이터를 다룰 때 적합합니다.
TryParse() 시리즈
int.TryParse() 외에도 다양한 기본형 타입에 대해 TryParse 메서드가 제공됩니다. 모두 string을 입력으로 받아 해당 타입으로 안전하게 변환할 수 있습니다.
float.TryParse("3.14", out float f); // 문자열 → float
bool.TryParse("true", out bool b); // 문자열 → bool
이들 역시 실패 시 예외 없이 false를 반환하며, out 변수는 해당 타입의 기본값으로 초기화됩니다.
다만 한가지...
int.TryParse() 는 변환에 실패하면 false 를 반환하지만, 왜 실패했는지는 알려주지 않습니다.
예를 들어 아래와 같은 다양한 실패 케이스가 있어도
// 문자 포함 – 잘못된 형식
int.TryParse("apple", out int a);
// 소수점 포함 – int로 변환 불가
int.TryParse("3.14", out int b);
// 너무 큰 숫자 – int 범위 초과
int.TryParse("999999999999999", out int c);
세 경우 모두 결과는 단순히 false, 변수는 0으로 초기화됩니다. 즉, "실패했다"는 정보만 주고, 왜 실패했는지는 감춥니다. TryParse()는 빠르고 예외가 없다는 장점이 있지만, 정확한 실패 원인을 파악해야 할 경우에는 추가 로직이 필요합니다.
마무리
* 숫자 형식이 확실한 경우에는 Convert.ToInt32() 가 간단하지만, 예외 발생 시 성능에 영향을 줄 수 있습니다.
* 사용자 입력 등 실패 가능성이 있는 데이터는 int.TryParse() 로 처리하는 것이 안정적이고 효율적입니다
* 예외는 “진짜 예외적인 상황”에만 사용하는 것이 좋으며, 흐름 제어 용도로 쓰는 것은 지양하는 것이 바람직합니다
'C#' 카테고리의 다른 글
C# 에서 ref, out, in 키워드 정리 (0) | 2025.04.02 |
---|---|
C# 에서 readonly 는 참조 타입에서 어떻게 동작할까? (0) | 2025.04.01 |
List<T> 의 동작 방식 (0) | 2025.03.16 |
람다 표현식을 사용할 때 헤깔리는 이유 (0) | 2025.03.15 |
delegate 를 기반으로 한 상태 기계 구현해보기 (0) | 2025.03.12 |