Section 27.3: SortedSet<T>

// 비어있는 Set 을 새로 생성한다 var mySet = new SortedSet<int>(); // Set 에 항목을 추가한다 // 항목 '1' 을 추가하기 전에 항목 '2' 를 먼저 추가하였음에 유의한다 mySet.Add(2); mySet.Add(1); // Set 의 내용물들을 요소 반복한다 foreach(var item in mySet) { Console.WriteLine(item); } // 출력 결과: // 1 // 2
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 27.2: Dictionary<TKey, TValue>

Dictionary<TKey, TValue> 은 일종의 map 이라고 할 수 있다. 하나의 Dictionary 내에서는 주어진 key 에 대하여 오직 하나의 value 만이 존재할 수 있다.

using System.Collections.Generic; var people = new Dictionary<string, int> { { "John", 30 }, {"Mary", 35}, {"Jack", 40} }; // 데이터 읽기 Console.WriteLine(people["John"]); // 30 Console.WriteLine(people["George"]); // KeyNotFoundException 을 발생시킨다 int age; if (people.TryGetValue("Mary", out age)) { Console.WriteLine(age); // 35 } // 데이터를 추가 및 변경하기 people["John"] = 40; // 이러한 방식으로 값을 덮어쓸 수 있다 people.Add("John", 40); // "John" 이라는 key 가 이미 존재하므로 ArgumentException 을 발생시킨다 // 요소 반복 수행하기 (iterate) foreach(KeyValuePair<string, int> person in people) { Console.WriteLine("Name={0}, Age={1}", person.Key, person.Value); } foreach(string name in people.Keys) { Console.WriteLine("Name={0}", name); } foreach(int age in people.Values) { Console.WriteLine("Age={0}", age); }

컬렉션 초기화 (collection initialization) 수행시에 중복된 키를 선언한 경우:

var people = new Dictionary<string, int> { { "John", 30 }, {"Mary", 35}, {"Jack", 40}, {"Jack", 40} }; // "Jack" 이라는 key 가 이미 존재하므로 ArgumentException 을 발생시킨다
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 27.1: HashSet<T>

HashSet 은 각각의 유일한 요소들만이 저장되어 있는 컬렉션으로, 요소 검색시 O(1) 시간 복잡도를 갖는다.

HashSet<int> validStoryPointValues = new HashSet<int>() { 1, 2, 3, 5, 8, 13, 21 }; bool containsEight = validStoryPointValues.Contains(8); // O(1)

비교를 위해 ListContains 를 수행하는 경우를 생각해 보면, 이는 훨씬 뒤떨어지는 성능을 보여준다:

List<int> validStoryPointValues = new List<int>() { 1, 2, 3, 5, 8, 13, 21 }; bool containsEight = validStoryPointValues.Contains(8); // O(n)

HashSet.Contains 는 해시테이블을 사용하므로, 해당 컬렉션이 가지고 있는 요소들의 수에 관계 없이 언제나 매우 빠른 검색 속도를 보여 준다.

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 26.5: 컬렉션 초기자 (Collection Initializer) 에서 배열을 인자로 받기

아래와 같은 방법으로, 일반적인 인자와 더불어 배열을 컬렉션 초기자의 인자로 혼합하여 사용할 수 있다:

public class LotteryTicket: IEnumerable { public int[] LuckyNumbers; public string UserName; public void Add(string userName, params int[] luckyNumbers) { UserName = userName; Lottery = luckyNumbers; } }

이제 아래와 같은 문법을 사용할 수 있다:

var Tickets = new List<LotteryTicket>{ {"Mr Cool" , 35663, 35732, 12312, 75685}, {"Bruce" , 26874, 66677, 24546, 36483, 46768, 24632, 24527}, {"John Cena", 25446, 83356, 65536, 23783, 24567, 89337} }
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 26.4: 객체 초기자 (Object initializer) 내에서 컬렉션 초기자 (Collection initializer) 사용하기

public class Tag { public IList<string> Synonyms { get; set; } }

Synonyms 는 컬렉션 타입의 속성 값 (property) 이다. Tag 객체를 객체 초기자 (object initializer) 문법을 통해 생성시킬 때, Synonyms 역시 컬렉션 초기자 (collection initializer) 문법을 사용하여 초기화 시킬 수 있다:

Tag t = new Tag { Synonyms = new List<string> {"c#", "c-sharp"} };

이러한 컬렉션한 속성 값을 읽기 전용으로 선언한다고 하더라도, 여전히 컬렉션 초기자 문법을 사용할 수 있다. 아래에 수정된 예제가 제시되어 있다. (Synonyms 의 속성값이 private setter 를 가지도록 변경되었다):

public class Tag { public Tag() { Synonyms = new List < string > (); } public IList < string > Synonyms { get; private set; } }

이러한 경우에도 아래와 같은 방법으로 Tag 객체를 생성할 수 있다:

Tag t = new Tag { Synonyms = {"c#", "c-sharp"} };

이러한 동작이 가능한 이유는 컬렉션 초기자 (collection initializer) 가 사실은 Add() 메소드를 호출하여주는 일종의 문법적 간편화 장치 (syntactic sugar) 에 불과하기 때문이다. 위 코드에서 실제로 새로운 List 생성이 일어나지는 않으며, 컴파일러가 기존에 이미 생성된 객체에 대하여 Add() 메소드에 대한 호출을 자동 생성해 줄 뿐이다.

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 26.3: 사용자 정의 class 를 컬렉션 초기자 (Collection initializer) 로 초기화하기

특정 class 가 컬렉션 초기자 (Collection initializer) 를 지원하기 위해서는, 해당 class 가 IEnumerable 인터페이스를 상속받아야 하며, 또한 최소한 하나의 Add 메소드를 가져야 한다. C# 6 부터는, extension method 를 사용하여 IEnumerable을 상속받는 어떠한 collection 일지라도 사용자가 정의한 Add 메소드를 추가해줄 수 수 있다.

class Program { static void Main() { var col = new MyCollection { "foo", { "bar", 3 }, "baz", 123.45 d, }; } } class MyCollection: IEnumerable { private IList list = new ArrayList(); public void Add(string item) { list.Add(item) } public void Add(string item, int count) { for (int i = 0; i < count; i++) { list.Add(item); } } public IEnumerator GetEnumerator() { return list.GetEnumerator(); } } static class MyCollectionExtensions { public static void Add(this MyCollection @this, double value) => @this.Add(value.ToString()); }
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 26.2: C# 6 인덱스 초기자 (Index initializer)

C# 6 부터는, indexer 를 가진 collection 들의 경우 초기값을 할당할 인덱스를 대괄호로 둘러싼 후, 등호 및 초기값을 명시하는 방법으로 초기화를 수행할 수 있다.

Dictionary 초기화하기

Dictionary 를 위에서 소개한 문법을 이용하여 초기화하는 예제:

var dict = new Dictionary<string, int> { ["key1"] = 1, ["key2"] = 50 };

위 예제는 아래 코드와 동일하다:

var dict = new Dictionary<string, int>(); dict["key1"] = 1; dict["key2"] = 50;

C# 6 이전의 컬렉션 초기자 (Collection initializer) 문법을 이용하여 동일한 초기화 작업을 수행하는 코드를 작성해보면 다음과 같다:

var dict = new Dictionary<string, int> { { "key1", 1 }, { "key2", 50 } };

위 코드는 다음과 같은 작업을 수행할 것이다:

var dict = new Dictionary<string, int>(); dict.Add("key1", 1); dict.Add("key2", 50);

따라서, 이 새로운 문법은 실제 기능상에서 큰 차이가 있음을 알 수 있는데, 그것은 바로 객체의 Add() 메소드를 호출하는 기존 방식 대신에, 초기화될 객체의 indexer 를 사용하여 값 할당이 이루어 진다는 점이다. 이것이 의미하는 바는, 이 새로운 문법은 public 하게 사용 가능한 indexer 하나만을 필요로 한다는 것이며, 그러한 indexer 가 있는 어떠한 객체들에도 사용 가능하다는 점이다.

public class IndexableClass { public int this[int index] { set { Console.WriteLine("{0} was assigned to index {1}", value, index); } } } var foo = new IndexableClass { [0] = 10, [1] = 20 }

위 코드의 실행 결과는 다음과 같다:

10 was assigned to index 0 20 was assigned to index 1
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 26.1: 컬렉션 초기자 (Collection initializer)

컬렉션 타입을 특정 요소 값들로 초기화 시키기:

var stringList = new List<string> { "foo", "bar", };

컬렉션 초기자는 Add() 호출을 대신해주는 일종의 문법적 간편화 장치 (syntactic sugar) 로 볼 수 있다. 위 예제는 아래 코드와 동일하다:

var temp = new List<string>(); temp.Add("foo"); temp.Add("bar"); var stringList = temp;

여기서 눈여겨 볼 점은, 경쟁 조건 (race condition) 을 피하기 위해 임시 변수를 사용하여 초기화 과정이 원자적 (atomic) 으로 이루어진다는 점이다.

역주: 임시 변수를 사용하지 않고 stringList 에 직접 Add() 를 반복할 경우, "foo" 와 "bar" 사이에 다른 스레드에서 요소를 추가한다거나 하는 경우가 생길 수 있습니다.

Add() 메소드가 복수개의 파라미터를 처리할 수 있는 타입들에 대해서는, 쉼표로 분리된 (comma-separated) 인자 값들을 중괄호로 감싸 초기화 시킬 수 있다:

var numberDictionary = new Dictionary<int, string> { { 1, "One" }, { 2, "Two" }, };

위 예제는 다음 코드와 동일하다:

var temp = new Dictionary<int, string>(); temp.Add(1, "One"); temp.Add(2, "Two"); var numberDictionarynumberDictionary = temp;
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts