컬렉션 식 활용

  • 7 minutes to read

이번 글에서는 C# 컬렉션 식(Collection Expression)을 통해 코드를 더 깔끔하고 효율적으로 만드는 방법을 살펴보겠습니다. 컬렉션 이니셜라이저(Collection Initializer)와 컬렉션 식, 스프레드(Spread) 문법 등을 다루며, 지원되는 컬렉션 타입도 알아보겠습니다. 이 기능들은 C# 개발자의 작업 효율을 높이고 코드 가독성(Readability)을 향상시키는 데 도움이 될 것입니다.

컬렉션 식의 도입

C# 12.0에서는 컬렉션을 일관성 있는 문법으로 초기화할 수 있는 컬렉션 식(Collection Expression)이 도입되었습니다. 기존의 이니셜라이저 방식과 같은 기능을 하면서도 더 간결한 코드를 작성할 수 있도록 돕습니다. 대괄호 []로 표현되는 컬렉션 식은 개발자가 코드를 더 쉽게 이해할 수 있게 합니다.

초기화 방법

다음은 정수 배열을 다양한 방법으로 초기화하는 예시입니다.

var numbers1 = new int[3] { 1, 2, 3 };
var numbers2 = new int[] { 1, 2, 3 };
var numbers3 = new[] { 1, 2, 3 };
int[] numbers4 = { 1, 2, 3 };

이 모든 방식은 같은 결과를 만들어냅니다. 새로운 컬렉션 식은 이니셜라이저(Initializer)의 중괄호 {} 대신 대괄호 []를 사용합니다.

List<char> name = [ 'A', 'l', 'i', 'c', 'e' ];

컬렉션 식은 var 키워드와 함께 사용할 수 없으며, 반드시 컬렉션 타입을 명시해야 합니다. 다음과 같이 var를 사용할 경우 오류가 발생합니다.

// 오류 CS9176: 컬렉션 식에 대한 대상 타입이 없습니다.
// Error CS9176: No target type for the collection expression.
var collection = [1, 2, 3];

일관된 문법으로 컬렉션을 표현하는 컬렉션 식은 가독성(Readability)과 유지보수성(Maintainability)을 향상시킵니다.

다양한 형태의 컬렉션 식

컬렉션이 비어있을 경우에도 표현식을 사용할 수 있습니다:

int[] emptyCollection = [];

컬렉션 식을 통해 기존의 new 키워드 방식보다 메모리를 더 효율적으로 활용할 수 있습니다. 인터페이스(Interface)를 사용해 컬렉션을 초기화할 때에도 컬렉션 식을 활용할 수 있습니다.

스프레드 기능

스프레드(Spread) 문법은 다른 컬렉션의 요소를 현재 컬렉션에 결합할 때 간결하게 표현하는 기능입니다.

int[] numbers1 = [1, 2, 3];
int[] numbers2 = [4, 5, 6];

int[] all = [..numbers2, 100, ..numbers1];

Console.WriteLine(string.Join(", ", all));
Console.WriteLine($"길이: {all.Length}");
// 출력(Output):
//   4, 5, 6, 100, 1, 2, 3
//   길이(Length): 7

스프레드 기능은 foreach로 순회할 수 있는 모든 컬렉션에 적용할 수 있습니다.

지원되는 컬렉션 타입

컬렉션 식은 대부분의 컬렉션 타입을 지원합니다. BCL(Base Class Library)의 주요 컬렉션이 이미 업데이트되었고, 지원되지 않는 경우에도 속성(Property)이나 빌더 패턴(Builder Pattern)을 활용할 수 있습니다. 다만 현재 사전(Dictionary) 타입은 지원되지 않습니다.

리팩터링 예시

컬렉션 식은 다양한 상황에서 유용합니다.

  • 널(Null)이 될 수 없는 컬렉션 타입 필드(Field), 속성(Property), 로컬 변수(Local Variable)를 초기화할 때
  • 컬렉션 타입 매개변수(Parameter)를 받는 메서드(Method)에 인수로 전달할 때

다음은 컬렉션 이니셜라이저를 컬렉션 식으로 리팩터링한 예시입니다.

원본 소스는 다음과 같습니다.

public IEnumerable<Customer> Get()
{
    return new List<Customer>
    {
        new Customer { Id = 1, Name = "김태영", City = "서울" },
        new Customer { Id = 2, Name = "박용준", City = "인천" },
        new Customer { Id = 3, Name = "한상훈", City = "경기" }
    };
}

컬렉션 식으로 다음과 같이 줄일 수 있습니다.

public IEnumerable<Customer> Get()
{
    return
    [
        new Customer { Id = 1, Name = "김태영", City = "서울" },
        new Customer { Id = 2, Name = "박용준", City = "인천" },
        new Customer { Id = 3, Name = "한상훈", City = "경기" }
    ];
}

식 본문을 사용하여 한 번 더 줄일 수 있습니다.

public IEnumerable<Customer> Get() => [
        new Customer { Id = 1, Name = "김태영", City = "서울" },
        new Customer { Id = 2, Name = "박용준", City = "인천" },
        new Customer { Id = 3, Name = "한상훈", City = "경기" }
    ];

다음은 EventRegistry 개체를 초기화하는 예시입니다.

namespace EventManagement;

public sealed class EventRegistry
{
    private readonly HashSet<Event> _events = [];

    public Guid RegisterEvent(Event newEvent)
    {
        _ = _events.Add(newEvent);
        return newEvent.Id;
    }

    public void RemoveEvent(Guid id)
    {
        _ = _events.RemoveWhere(x => x.Id == id);
    }
}

public record Event(
    bool IsActive,
    string? ErrorDetails)
{
    public Guid Id { get; } = Guid.NewGuid();
}

new HashSet<Event>()[]로 간단하게 표현할 수 있습니다.

Span<T>ReadOnlySpan<T> 지원

컬렉션 식은 Span<T>ReadOnlySpan<T>를 지원합니다.

Span<int> numbers = [1, 2, 3, 4, 5];
ReadOnlySpan<char> name = ['A', 'l', 'i', 'c', 'e'];

효율적인 메모리 사용을 통해 성능을 향상시킬 수 있습니다.

컬렉션 식 장점

컬렉션 식은 기존 이니셜라이저보다 효율적인 코드를 생성합니다.

List<int> someList = new() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

이니셜라이저는 Add 메서드를 사용하지만, 컬렉션 식은 AddRange를 사용해 최적화된 코드를 생성합니다.

더 깊이 공부하고 싶다면
DevLec에서는 실무 중심의 C#, .NET, ASP.NET Core, Blazor, 데이터 액세스 강좌를 단계별로 제공합니다. 현재 수강 가능한 강좌 외에도 더 많은 과정이 준비되어 있습니다.
DevLec.com에서 자세한 커리큘럼을 확인해 보세요.
DevLec 공식 강의
C# Programming
C# 프로그래밍 입문
프로그래밍을 처음 시작하는 입문자를 위한 C# 기본기 완성 과정입니다.
ASP.NET Core 10.0
ASP.NET Core 10.0 시작하기 MVC Fundamentals Part 1 MVC Fundamentals Part 2
웹 애플리케이션의 구조와 MVC 패턴을 ASP.NET Core로 실습하며 익힐 수 있습니다.
Blazor Server
풀스택 웹개발자 과정 Part 1 풀스택 웹개발자 과정 Part 2 풀스택 웹개발자 과정 Part 3
실무에서 바로 활용 가능한 Blazor Server 기반 관리자·포털 프로젝트를 만들어 봅니다.
Data & APIs
Entity Framework Core 시작하기 ADO.NET Fundamentals Blazor Server Fundamentals Minimal APIs
데이터 액세스와 Web API를 함께 이해하면 실무 .NET 백엔드 개발에 큰 도움이 됩니다.
VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com