연습 - Clear() 및 Resize() 살펴보기
- 15분
물류 회사를 위해 팔레트 추적기 개발을 계속 진행함에 따라 새 팔레트는 추적하고 오래된 팔레트는 추적 시스템에서 제거해야 할 수 있습니다. 그렇다면 팔레트를 추가하고 제거할 수 있는 추적 기능을 만들려면 어떻게 해야 할까요?
배열 메서드를 사용하여 배열 지우기 및 크기 조정
Array.Clear() 메서드를 사용하면 배열에서 특정 요소의 콘텐츠를 제거하고 이를 배열 기본값으로 바꿀 수 있습니다. 예를 들어 string 배열에서 요소를 지우면 지워진 값이 null(으)로 바뀝니다. 마찬가지로 int 배열에서 요소를 지우면 0(0)이(가) 대체합니다.
반면에 Array.Resize() 메서드를 사용하면 배열에 요소를 추가하거나 제거할 수 있습니다.
//줄 주석 연산자를 삭제하거나 사용하여 이전 연습의 모든 코드를 주석 처리합니다.다음과 같이 Visual Studio Code 편집기에서 코드를 업데이트합니다.
string[] pallets = [ "B14", "A11", "B12", "A13" ]; Console.WriteLine(""); Array.Clear(pallets, 0, 2); Console.WriteLine($"Clearing 2 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); }참고 항목
이 예제에서는 C# 12에서 도입되고 .NET 10에서 지원되는 컬렉션 식 구문을 사용합니다.
잠시 시간을 내어
Array.Clear(pallets, 0, 2);코드 줄을 중점적으로 살펴봅니다.여기서는 인덱스
Array.Clear()부터 시작하고pallets개 요소를 지우는0배열의 요소에 저장된 값을 지우는 데2메서드를 사용합니다.Visual Studio Code 파일 메뉴에서 저장을 선택합니다.
코드를 빌드하거나 실행하기 전에 Program.cs 파일을 저장해야 합니다.
탐색기 패널에서 TestProject 폴더 위치에서 터미널을 열려면 TestProject를 마우스 오른쪽 단추로 클릭한 다음 통합 터미널에서 열기를 선택합니다.
터미널 패널이 열려 있어야 하고 터미널이 TestProject 폴더 위치에 열려 있음을 보여 주는 명령 프롬프트를 포함해야 합니다.
터미널 명령 프롬프트에서 코드를 실행하려면 dotnet run을 입력한 다음, Enter 키를 누릅니다.
참고 항목
“실행할 프로젝트를 찾을 수 없습니다.”라는 메시지가 표시되면 터미널 명령 프롬프트에 예상되는 TestProject 폴더 위치가 표시되는지 확인합니다. 예:
C:\Users\someuser\Desktop\csharpprojects\TestProject>코드를 실행하면 배열의 처음 두 요소에 저장된 값이 지워진 것을 알 수 있습니다. 요소는
Length속성 및foreach문에 계속 존재하지만 이제 비어 있습니다.Clearing 2 ... count: 4 -- -- -- B12 -- A13
빈 문자열 및 null
Array.Clear()를 사용하면 지워진 요소는 더 이상 메모리에서 문자열을 참조하지 않습니다. 실제로 요소는 아무것도 가리키지 않습니다. 아무 것도 가리키지 않는 것은 처음에는 이해하기 어려울 수 있는 중요한 개념입니다.
Array.Clear() 메서드의 영향을 받은 요소의 값을 검색하려고 하면 어떻게 되나요? 검색할 수 있나요?
지워진 요소의 값에 액세스
C# 컴파일러가 null 값으로 작동하는 방식을 확인하기 위해 지워진 요소의 값을 확인하려면 두 가지 접근 방식이 필요합니다.
다음과 같이
Array.Clear(pallets, 0, 2);코드 줄 주위에 새 코드 줄을 삽입합니다.Console.WriteLine($"Before: {pallets[0]}"); Array.Clear(pallets, 0, 2); Console.WriteLine($"After: {pallets[0]}");이 코드가 다음 코드 목록과 일치하는지 확인합니다.
string[] pallets = [ "B14", "A11", "B12", "A13" ]; Console.WriteLine(""); Console.WriteLine($"Before: {pallets[0]}"); Array.Clear(pallets, 0, 2); Console.WriteLine($"After: {pallets[0]}"); Console.WriteLine($"Clearing 2 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); }코드 파일을 저장한 다음, Visual Studio Code를 사용하여 코드를 실행합니다.
다음 출력이 표시됩니다.
Before: B14 After: Clearing 2 ... count: 4 -- -- -- B12 -- A13
출력 After: 줄을 중점적으로 살펴보면 pallets[0]에 저장된 값이 빈 문자열이라고 생각할 수 있습니다. 그러나 C# 컴파일러는 표시를 위해 null 값을 빈 문자열로 암시적으로 변환합니다.
지워진 요소에 대한 문자열 도우미 메서드 호출
지워진 후 pallets[0]에 저장된 값이 null임을 증명하려면 ToLower()에서 pallets[0] 메서드를 호출하도록 코드 예제를 수정합니다. 문자열인 경우 코드가 제대로 작동합니다. 그러나 null인 경우 코드에서 예외가 throw됩니다.
콘솔에
ToLower()을 쓰려고 할 때마다pallets[0]메서드를 호출하려면 다음과 같이 코드를 업데이트합니다.Console.WriteLine($"Before: {pallets[0].ToLower()}"); Array.Clear(pallets, 0, 2); Console.WriteLine($"After: {pallets[0].ToLower()}");코드가 다음 코드 목록과 일치하는지 확인합니다.
string[] pallets = [ "B14", "A11", "B12", "A13" ]; Console.WriteLine(""); Console.WriteLine($"Before: {pallets[0].ToLower()}"); Array.Clear(pallets, 0, 2); Console.WriteLine($"After: {pallets[0].ToLower()}"); Console.WriteLine($"Clearing 2 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); }코드 파일을 저장한 다음, Visual Studio Code를 사용하여 코드를 실행합니다. 이번에는 코드를 실행할 때 긴 오류 메시지가 표시됩니다. 텍스트를 구문 분석하면 다음 메시지가 표시됩니다.
System.NullReferenceException: Object reference not set to an instance of an object.이 예외는 C# 컴파일러가 null을 빈 문자열로 암시적으로 변환하기 전에
pallets[0]요소의 콘텐츠에서 메서드를 호출하려는 시도가 발생하기 때문에 throw됩니다.이 사례를 통해
Array.Clear()(은)는 배열 요소의 값에 대한 참조(있는 경우)를 제거한다는 것을 알 수 있습니다. 이 문제를 해결하려면 값을 인쇄하기 전에 null을 확인합니다.오류를 방지하기 위해 null일 수 있는 배열 요소에 액세스하기 전에
if문을 추가합니다.
if (pallets[0] != null)
Console.WriteLine($"After: {pallets[0].ToLower()}");
배열의 크기를 조정하여 더 많은 요소 추가
그런 다음, 1단계의 코드 목록을 다시 작성하여 배열의 크기를 조정하는 코드를 포함합니다. 작업이 완료되면 코드가 다음 코드 목록과 일치해야 합니다.
string[] pallets = ["B14", "A11", "B12", "A13" ]; Console.WriteLine(""); Array.Clear(pallets, 0, 2); Console.WriteLine($"Clearing 2 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); } Console.WriteLine(""); Array.Resize(ref pallets, 6); Console.WriteLine($"Resizing 6 ... count: {pallets.Length}"); pallets[4] = "C01"; pallets[5] = "C02"; foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); }잠시 시간을 내어 줄
Array.Resize(ref pallets, 6);을 중점적으로 살펴봅니다.여기서는
Resize()키워드를 사용하여 참조를 통해pallets배열을 전달하는ref메서드를 호출합니다. 경우에 따라 메서드를 사용하려면 값(기본값) 또는 참조(ref 키워드 사용)로 인수를 전달해야 합니다. 이 작업이 필요한 이유를 알아보려면 .NET에서 개체를 관리하는 방법에 관한 길고 복잡한 설명이 필요합니다. 아쉽게도 해당 설명은 이 모듈의 범위를 벗어납니다. 잘 모르겠다면 지정된 메서드를 제대로 호출하는 방법 관련 예제에 대한 Intellisense 또는 Microsoft Docs를 확인하는 것이 좋습니다.이 경우 요소 4개에서
pallets개로6배열의 크기를 조정합니다. 새 요소는 현재 요소의 끝에 추가됩니다. 두 개의 새 요소는 값을 할당할 때까지 null이 됩니다.코드 파일을 저장한 다음, Visual Studio Code를 사용하여 코드를 실행합니다. 코드를 실행하면 다음과 같은 출력이 표시됩니다.
Clearing 2 ... count: 4 -- -- -- B12 -- A13 Resizing 6 ... count: 6 -- -- -- B12 -- A13 -- C01 -- C02
배열의 크기를 조정하여 요소 제거
반대로, Array.Resize()를 사용하여 배열 요소를 제거할 수 있습니다.
다음과 같이 Visual Studio Code 편집기에서 코드를 업데이트합니다.
string[] pallets = [ "B14", "A11", "B12", "A13" ]; Console.WriteLine(""); Array.Clear(pallets, 0, 2); Console.WriteLine($"Clearing 2 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); } Console.WriteLine(""); Array.Resize(ref pallets, 6); Console.WriteLine($"Resizing 6 ... count: {pallets.Length}"); pallets[4] = "C01"; pallets[5] = "C02"; foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); } Console.WriteLine(""); Array.Resize(ref pallets, 3); Console.WriteLine($"Resizing 3 ... count: {pallets.Length}"); foreach (var pallet in pallets) { Console.WriteLine($"-- {pallet}"); }코드 파일을 저장한 다음, Visual Studio Code를 사용하여 코드를 실행합니다. 코드를 실행하면 다음과 같은 출력이 표시됩니다.
Clearing 2 ... count: 4 -- -- -- B12 -- A13 Resizing 6 ... count: 6 -- -- -- B12 -- A13 -- C01 -- C02 Resizing 3 ... count: 3 -- -- -- B12Array.Resize()를 호출해도 처음 두 개의 null 요소는 제거되지 않습니다. 오히려 마지막 세 개의 요소를 제거했습니다. 특히 마지막 세 개 요소는 문자열 값이 포함되어 있어도 제거되었습니다.
배열에서 null 요소를 제거할 수 있나요?
Array.Resize() 메서드가 배열에서 빈 요소를 제거하지 않는 경우 이 작업을 자동으로 수행할 다른 도우미 메서드가 있나요? 아니요. 배열에서 요소를 비우는 가장 좋은 방법은 각 항목을 반복하여 null이 아닌 요소 수를 계산하고 변수(카운터)를 증분하는 것입니다. 다음으로, 카운터 변수의 크기인 두 번째 배열을 만듭니다. 마지막으로 원래 배열의 각 요소를 반복하고 null이 아닌 값을 새 배열에 복사합니다.
요약
이 단원에서 설명한 몇 가지 중요한 아이디어는 다음과 같습니다.
-
Clear()메서드를 사용하여 배열의 요소에서 값을 비웁니다. -
Resize()메서드를 통해 배열의 요소 수를 변경하여 배열의 끝에서 요소를 제거하거나 추가합니다. - 새 배열 요소와 지워진 요소는 null이며, 메모리에서 값을 가리키지 않음을 의미합니다.