성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# 12 - 컬렉션 식(Collection Expressions)</h1> <p> 이 문법은 현재(2023-09-18) "17.7 Preview 5"에 구현됐으므로 (17.7.4 정식 버전이 아닌) Preview 버전에서 테스트할 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이번 구문은 파이썬/자바스크립트 등의 영향을 받았을 듯한데요, 컬렉션을 위한 초기화 구문으로 새롭게 대괄호([, ])를 지원하게 되었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // C# 11 이전 int[] a = { 1, 2, 3, 4, 5, 6, 7, 8 }; // C# 12부터 추가로 지원 int[] a = [1, 2, 3, 4, 5, 6, 7, 8]; </pre> <br /> 대괄호를 이용한 초기화 식은 위의 예제처럼 배열뿐만 아니라, Span(ReadOnlySpan)과 (C# 3.0의) Collection Initializer를 지원하는 타입 및 (C# 6.0의 확장 메서드로 추가할 수 있는) Add 이름을 갖는 메서드를 구현한 IEnumerable 상속 타입 또는 (Add를 포함하고 있으므로) ICollection 인터페이스를 구현한 타입에 적용할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System.Collections; namespace ConsoleApp2; internal class Program { static void Main(string[] args) { // C# 11 이하에서는 Span 초기화는 나눠서 했던 반면, int[] a = { 1, 2, 3, 4, 5, 6, 7, 8 }; Span<int> ints1 = a; // C# 12부터는 컬렉션 리터럴을 활용해 한 줄로 처리 가능 <span style='color: blue; font-weight: bold'>Span<int> ints2 = [1, 2, 3, 4, 5, 6, 7, 8];</span> // "IEnumerable + Add 확장 메서드" 또는 ICollection 인터페이스를 구현한 경우 // C# 11 이하는 컬렉션 초기화 구문을 사용, MyType list1 = new MyType() { 1, 2, 3, 4, 5, 6, 7, 8 }; // C# 12부터는 컬렉션 리터럴 사용 가능 <span style='color: blue; font-weight: bold'>MyType list2 = [1, 2, 3, 4, 5, 6, 7, 8];</span> // 가변 배열의 경우에도 컬렉션 리터럴 사용 가능 <span style='color: blue; font-weight: bold'>int[][] jaggedArray = [[1, 2, 3], [4], [5, 6]];</span> } } public class <span style='color: blue; font-weight: bold'>MyType : IEnumerable</span> { public List<int> Values { get; set; } = new List<int>(); public IEnumerator GetEnumerator() { return Values.GetEnumerator(); } } public static class MyExtension { <span style='color: blue; font-weight: bold'>public static void Add(this MyType type, int value)</span> { type.Values.Add(value); } } </pre> <br /> 또한, 초기화 구문 자체가 "식(Expression)"으로 평가되기 때문에 이외의 코드에서도 식이 쓰일 수 있는 환경이면 모두 적용하는 것이 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 3항 연산자에도 쓸 수 있고, List<int> list = (Environment.OSVersion.Version.Major > 4) ? <span style='color: blue; font-weight: bold'>[1, 2]</span> : <span style='color: blue; font-weight: bold'>[3, 4]</span>; ListArray(<span style='color: blue; font-weight: bold'>[1, 2, 3]</span>); // 함수의 인자로 직접 넘기는 것이 가능하며, static void ListArray(List<int> list) { } Array.ForEach(<span style='color: blue; font-weight: bold'>[3, 4, 5]</span>, (elem) => Console.Write($"{elem}, ")); // 요소에 대한 타입 추론 지원, int[]로 결정 public class TestType { // 람다 함수에서도 사용 가능 public List<int> GetDefaults <span style='color: blue; font-weight: bold'>=> [1, 2, 3]</span>; } // 하지만, 메서드의 (상수식을 요구하는) 기본 값으로는 설정할 수 없음 public void Output(int[] elems = <span style='color: blue; font-weight: bold'>[1, 2, 3]</span>) // 컴파일 오류: error CS1736: Default parameter value for 'elems' must be a compile-time constant { } </pre> <br /> 이와 함께, 자바스크립트에서 지원하는 스프레드 연산자도 새롭게 추가되었습니다. 단지 차이점이라면 자바스크립트는 3개의 점이었지만 C# 12의 스프레드 연산자는 2개의 점으로 이뤄져 있습니다. 어쨌든 새로운 연산자를 이용하면 기존 목록을 연결하는 코드를 간단하게 표현할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > int[] array1 = [1, 2, 3]; int[] array2= [4]; int[] array3 = [5, 6]; int[] array = [0, <span style='color: blue; font-weight: bold'>..array1, ..array2, ..array3</span>]; Array.ForEach(array, (elem) => Console.Write($"{elem}, ")); // 출력 결과: 0, 1, 2, 3, 4, 5, 6, </pre> <br /> <strike>단지, 아직은 타입 추론 기능이 경우의 수를 모두 고려하진 않은 듯하므로 다음의 코드는 컴파일이 안 됩니다.</strike> 정식 버전에서 아래의 코드는 오류 없이 타입 추론이 돼 컴파일이 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // <strike>컴파일 에러: error CS0411: The type arguments for method 'Array.ForEach<T>(T[], Action<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.</strike> Array.ForEach(<span style='color: blue; font-weight: bold'>[0, .. array1]</span>, (elem) => Console.Write($"{elem}, ")); </pre> <br /> <strike>물론, 약간의 힌트만 주면 빌드가 완료됩니다. ^^</strike> 위의 코드는 아래와 같은 힌트를 주는 것과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Array.ForEach<span style='color: blue; font-weight: bold'><int></span>([0, .. array1], (elem) => Console.Write($"{elem}, ")); </pre> <br /> <hr style='width: 50%' /><br /> <br /> 당연하겠지만, 컬렉션 식의 사용은 결국 기존의 컬렉션 초기화 구문 또는 Add 함수를 호출하는 코드로 C# 컴파일러에 의해 자동으로 변경되는 식으로 처리됩니다.<br /> <br /> 예를 들어 아래의 C# 12 코드는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > int[] array1 = [1, 2, 3]; int[] array2 = [4]; int[] array3 = [5, 6]; int[] array = [0, .. array1, .. array2, .. array3]; </pre> <br /> 이렇게 사전 변경돼 컴파일 처리를 하게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > int[] array = <span style='color: blue; font-weight: bold'>new int[] { 1, 2, 3 }</span>; int[] array2 = <span style='color: blue; font-weight: bold'>new int[] { 4 }</span>; int[] array3 = <span style='color: blue; font-weight: bold'>new int[] { 5, 6 }</span>; List<int> list = new List<int>(); <span style='color: blue; font-weight: bold'>list.Add(0);</span> foreach (int item in array) { <span style='color: blue; font-weight: bold'>list.Add(item);</span> } foreach (int item in array2) { <span style='color: blue; font-weight: bold'>list.Add(item);</span> } foreach (int item in array3) { <span style='color: blue; font-weight: bold'>list.Add(item);</span> } </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1887
(왼쪽의 숫자를 입력해야 합니다.)