2024. 9. 22. 16:41ㆍ카테고리 없음
개요
예외 처리, 값형과 참조형에 대해 알아보겠습니다
내용 - 예외란?
- 예외는 프로그램 실행 중에 발생하는 예기치 않은 상황을 의미합니다.
- 예외는 프로그램의 정상적인 흐름을 방해하고 오류를 야기할 수 있습니다.
내용 - 예외 처리 구현
- C#에서는 try-catch 블록을 사용하여 예외 처리를 수행합니다.
- try 블록 내에서 예외가 발생할 수 있는 코드를 작성하고, catch 블록에서 예외를 처리합니다.
예외 처리 구현 코드
try
{
// 예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
// ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
// ExceptionType2에 해당하는 예외 처리
}
finally
{
// 예외 발생 여부와 상관없이 항상 실행되는 코드
}
내용 - finally 블록
- finally 블록은 예외 발생 여부와 상관없이 항상 실행되는 코드 블록입니다.
- finally 블록은 예외 처리의 마지막 단계로, 예외 발생 시 정리 작업이나 리소스 해제 등의 코드를 포함할 수 있습니다.
- finally 블록은 try-catch 블록 뒤에 작성되며, 생략할 수도 있습니다.
내용 - 사용자 정의 예외 처리
public class NegativeNumberException : Exception
{
public NegativeNumberException(string message) : base(message)
{
}
}
static void Main(string[] args)
{
try
{
int number = 110;
if (number < 0)
{
throw new NegativeNumberException("음수는 처리할 수 없습니다."); //일부러 코드 에러를 발생시킬때 throw를 사용한다.
}
}
catch (NegativeNumberException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}
}
코드설명
public NegativeNumberException(string message) : base(message) :
- base(message) 이부분이 이니셜라이저 이고, 이니셜라이저는 생성자가 실행 되기전에 처리할 것들을 명시해준다.
- base는 부모를 말한다.(Exception의 생성자를 먼저 처리하고 온다.)
- 진행 순서는 NegativeNumberException 이 실행이 되면 부모에 생성자를 먼저 메세지를 전달해서 동작을 하고 NegativeNumberException생성자가 동작을 한다.
내용 - 값형과 참조형
값형(Value Type)
- 값형은 변수에 값을 직접 저장합니다.
- 변수가 실제 데이터를 보유하고 있으며, 해당 변수를 다른 변수에 할당하거나 전달할 때는 값이 복사됩니다.
- 값형 변수의 수정은 해당 변수의 값만 변경하므로 다른 변수에 영향을 주지 않습니다.
- int, float, double, bool 등의 기본 데이터 타입들이 값형에 해당합니다.
참조형(Reference Type)
- 참조형은 변수가 데이터에 대한 참조(메모리 주소)를 저장합니다.
- 변수가 실제 데이터를 가리키는 참조를 갖고 있으며, 해당 변수를 다른 변수에 할당하거나 전달할 때는 참조가 복사됩니다.
- 참조형 변수의 수정은 동일한 데이터를 가리키고 있는 다른 변수에 영향을 줄 수 있습니다.
- 클래스, 배열, 인터페이스 등이 참조형에 해당합니다.
값형과 참조형의 차이점
- 값형은 실제 데이터를 변수에 저장하고, 참조형은 데이터에 대한 참조를 변수에 저장합니다.
- 값형은 변수 간의 값 복사가 이루어지고, 참조형은 변수 간의 참조 복사가 이루어집니다.
- 값형은 변수가 독립적으로 데이터를 가지며, 참조형은 변수가 동일한 데이터를 참조합니다.
내용 - 박싱과 언박싱
값형과 참조형 사이의 변환을 의미
박싱(Boxing)
- 박싱은 값형을 참조형으로 변환하는 과정을 말합니다.
- 값형 변수의 값을 메모리의 힙 영역에 할당된 객체로 래핑합니다.
- 박싱을 통해 값형이 참조형의 특징을 갖게 되며, 참조형 변수로 다뤄질 수 있습니다.
- 박싱된 값형은 참조로 전달되므로 메모리 오버헤드가 발생할 수 있습니다.
언박싱(Unboxing)
- 언박싱은 박싱된 객체를 다시 값형으로 변환하는 과정을 말합니다.
- 박싱된 객체에서 값을 추출하여 값형 변수에 할당합니다.
- 언박싱은 명시적으로 타입 캐스팅을 해야 하며, 런타임에서 타입 검사가 이루어집니다.
- 잘못된 형식으로 언박싱하면 런타임 에러가 발생할 수 있습니다.
박싱과 언박싱의 주요 특징
- 박싱과 언박싱은 값형과 참조형 사이의 변환 작업이므로 성능에 영향을 미칠 수 있습니다. 반복적인 박싱과 언박싱은 성능 저하를 초래할 수 있으므로 주의해야 합니다.
- 박싱된 객체는 힙 영역에 할당되므로 가비지 컬렉션의 대상이 될 수 있습니다. 따라서 메모리 관리에 유의해야 합니다.
- 박싱된 객체와 원래의 값형은 서로 독립적이므로 값을 수정하더라도 상호간에 영향을 주지 않습니다.
참고사항( object )
object는 .NET Common Type System (CTS)의 일부이며, 모든 클래스의 직간접적인 상위 클래스입니다. 모든 클래스는 object에서 상속되며, object는 모든 형식을 참조할 수 있는 포괄적인 타입입니다.
박싱과 언박싱 예시 코드
using System;
class Program
{
static void Main()
{
// 값형
int x = 10;
int y = x;
y = 20;
Console.WriteLine("x: " + x); // 출력 결과: 10
Console.WriteLine("y: " + y); // 출력 결과: 20
// 참조형
int[] arr1 = new int[] { 1, 2, 3 };
int[] arr2 = arr1;
arr2[0] = 4;
Console.WriteLine("arr1[0]: " + arr1[0]); // 출력 결과: 4
Console.WriteLine("arr2[0]: " + arr2[0]); // 출력 결과: 4
// 박싱과 언박싱
int num1 = 10;
object obj = num1; // 박싱
int num2 = (int)obj; // 언박싱
Console.WriteLine("num1: " + num1); // 출력 결과: 10
Console.WriteLine("num2: " + num2); // 출력 결과: 10
}
}
리스트 활용 예제
List<object> myList = new List<object>();
// 박싱: 값 형식을 참조 형식으로 변환하여 리스트에 추가
int intValue = 10;
myList.Add(intValue); // int를 object로 박싱하여 추가
float floatValue = 3.14f;
myList.Add(floatValue); // float를 object로 박싱하여 추가
// 언박싱: 참조 형식을 값 형식으로 변환하여 사용
int value1 = (int)myList[0]; // object를 int로 언박싱
float value2 = (float)myList[1]; // object를 float로 언박싱