. 박싱 : 값 타입을 참조 타입으로 변경하며, 이 과정에서 새롭게 생성된 참조 타입의 객체는 힙에 생성된다.
. 언 박싱 : 박싱되어 있는 참조타입의 객체로부터 값 타입 객체의 복사본을 가저온다. 스택에 생성된다.
박싱과 언박싱은 System.Object 타입이나 인터페이스 타입이 필요한 곳에서 값 타입을 사용하기 위해 반드시 필요한 메커니즘입니다. 하지만, 박싱과 언박싱이 수행되는 과정에서 생성되는 임시 객체로 예상치 못한 버그가 발생하기도 합니다.
또한, MSDN에 나오는 박싱과 언박싱의 성능에 대한 설명은 아래와 같습니다.
'값 형식이 박싱되면 완전히 새로운 개체가 생성되어야 합니다. 이 작업은 단순 참조 할당보다 20배나 오래 걸립니다. 언박싱 시 캐스팅 프로세스는 할당의 4배에 달하는 시간이 소요될 수 있습니다.'
박싱과 언박싱은 메모리와 속도 성능에도 좋지 않은 영향을 미치기 때문에 왠만하면 피하는 것이 좋습니다.
int firstNumber = 10; int SecondNumber = 15; float ThirdNumber = 1.5; Console.WriteLine($"A few numbers : {FirstNumber}, {SecondNumber}, {ThirdNumber}");
위의 단순한 코드에서 박싱의 예를 쉽게 찾아볼 수 있습니다.
보간 문자열을 만드는 작업은 System.Object 객체에 대한 배열을 사용합니다. 때문에 FirstNumber가 값 타입이라면 System.Object 타입으로 변환하기 위해 아래와 같은 박싱 과정을 수행합니다.
int i = 25; object o = i; // 박싱 o.ToString();
따라서, 값 타입의 객체를 직접 전달하지 말고 문자열 인스턴스를 전달하여 박싱을 피하는 것이 좋습니다.
. 컬렉션 사용을 피하고, 제네릭 컬렉션을 사용하라.
컬렉션은 C++의 STL처럼 C#에서 지원하는 자료구조입니다.
.NET 1.X의 컬렉션은 System.Object 타입의 객체에 대한 참조를 저장하도록 구현되어 있어 박싱/언박싱이 일어납니다.
이러한 문제에 대한 해결책으로 .NET 2.0에 제네릭 컬렉션이 나왔습니다. 박싱/언박싱이 일어나지 않도록 개체의 타입을 지정하여 사용하도록 하고 있습니다.
namespace Collection { class MainClass { static void Main(string[] args) { // 비 제네릭 컬렉션 ArrayList arrayList = new ArrayList(); arrayList.Add(1); arrayList.Add(2); arrayList.Add(3); Console.WriteLine("비 제네릭(ArrayList)"); foreach(var item in arrayList) { // var item == System.Object item int i = (int)item; // 언박싱 Console.WriteLine(i); } // 제네릭 컬렉션 List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); Console.WriteLine("제네릭(List)"); foreach(var item in list) { // var item == Int32 item Console.WriteLine(item); } } } }
참 고 : Effective C#
: https://076923.github.io/posts/C-9/
: http://www.mkexdev.net/Article/Content.aspx?parentCategoryID=1&categoryID=5&ID=670
'책 > Effective C#' 카테고리의 다른 글
Item 11. .NET 리소스 관리에 대한 이해 (0) | 2019.04.17 |
---|---|
Item 10. 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라. (0) | 2019.04.08 |
Item 8. 이벤트 호출 시에는 null 조건 연산자를 사용하라. (0) | 2019.04.04 |
Item 7. 델리게이트를 이용하여 콜백을 표현하라. (0) | 2019.03.27 |
Item 6. nameof( ) 연산자를 적극 활용하라. (0) | 2019.01.31 |