728x90
반응형
C#으로 코딩할 때 맨 상단에 위치하는 using ~~~ 지시문은 해당 네임스페이스를 가져와서 사용하겠다는 의미로 사용한다.
내가 별도로 만든 프로젝트 파일의 네임스페이스를 가져와서 사용하기도 하지만 C#에서 자체적으로 지원하는 .NET의 기본 네임스페이스를 보통 많이 사용한다.
System
- using System; 지시문을 사용해 선언한다.
- ms 공식 문서에는 using System에 포함된 수많은 클래스가 나와있다.
(https://learn.microsoft.com/ko-kr/dotnet/api/system?view=net-8.0)
- using System 내에서 범용적으로 사용하는 클래스나 네임스페이스는 다음과 같다.
- System.Console: 콘솔 입출력에 사용되는 클래스.
- System.String: 문자열을 나타내는 클래스.
- System.Int32, System.Double 등: 기본 데이터 타입을 나타내는 구조체.
- System.Collections.Generic: 제네릭 컬렉션을 포함하는 서브 네임스페이스.
- System.IO: 파일 및 데이터 스트림 입출력 클래스들을 포함하는 서브 네임스페이스.
Collections
- using System.Collections 지시문을 사용해 선언한다.
- 네임스페이스는 트리 구조로 조직화하는데, System이 루트 네임스페이스, Collections나 Collections.Generic이 서브 네임스페이스에 해당된다.
- Collections는 주로 자료구조와 관련된 클래스들을 가지고 있다.
- .Net 프레임워크에서 *비제네릭 컬렉션 클래스를 담당하는 대표적인 네임스페이스이다.
- Generic Collection이 .Net 프레임워크 2.0에서 업데이트 된 후 자료구조에 제너릭이 지원된 이후로는 성능 문제로 자주 사용하지 않는 편이다.
비제네릭*이란?
- 타입 매개변수를 선언하지 않는 클래스이다.
- 다양한 데이터 타입에 사용할 수 있지만 타입 안전성이 보장되지 않기 떄문에 타입 캐스팅에 상당히 신경 써 주어야 한다.
- 박싱과 언박싱이 필수적이라 성능 측면에서 효율적이라고는 볼 수 없다.
Collections 내의 주요 클래스
각 자료구조에 대한 자세한 설명은 블로그 내에 자료구조 탭에서 자세히 설명하겠습니다.
1. ArrayList
- 크기가 가변적인 배열이며 다양한 타입의 객체가 저장이 가능하다.
- 인덱스를 사용해 요소(데이터)에 접근이 가능하다.
- List와의 차이점은 자료형을 미리 선언하지 않아도 된다는 점이 있다.
using System;
using System.Collections;
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(10);
arrayList.Add("hi");
arrayList.Add(3.1);
}
}
2. Hashtable
- 키 - 값 (key - value) 형식으로 데이터를 저장하는 자료구조이다.
- Dictionary와는 다르게 key와 value 모두 어떤 타입이든 선언할 수 있다.
- 박싱과 언박싱이 일어난다.
using System;
using System.Collections;
class Program
{
static void Main()
{
Hashtable hashtable = new Hashtable();
hashtable.Add("key1", "value1");
hashtable.Add("key2", 2);
hashtable.Add("key3", 3.0);
}
}
3. Stack
- LIFO(Last-In-First-Out) 방식으로 데이터를 저장하는 컬렉션이다.
- Push로 요소를 추가하고, Pop으로 요소를 제거한다.
using System;
using System.Collections;
class Program
{
static void Main()
{
Stack stack = new Stack();
stack.Push("first");
stack.Push("second");
stack.Push("third");
}
}
4. Queue
- FIFO(First-In-First-Out) 방식으로 데이터를 저장하는 컬렉션이다.
- Enqueue로 요소를 추가하고, Dequeue로 요소를 제거한다.
using System;
using System.Collections;
class Program
{
static void Main()
{
Queue queue = new Queue();
queue.Enqueue("one");
queue.Enqueue("two");
queue.Enqueue("three");
}
}
Generic Collection
- System.Collections.Generic 지시문을 사용해 선언한다.
- Collections 에서는 데이터 타입을 명시하지 않았지만 Generic에서는 필수적으로 명시해야 한다.
- 미리 데이터 타입을 정의하기 때문에 타입 안정성이 확보되며 컴파일 시간에 타임에 타입 검사를 수행해 런타임 오류가 줄어든다.
- 박싱과 언박싱의 과정이 이루어지지 않기 때문에 성능이 올라간다.
Generic Collection 내의 주요 클래스
1. List<T>
List<T>에서 T는 제네릭 타입 매개변수(Type Parameter)를 의미함.
- 가변 크기의 배열로, 배열과 유사하지만 크기를 동적으로 조정할 수 있다.
- 인덱스를 사용하여 요소에 접근할 수 있다.
- ArrayList와 유사하지만 데이터 타입을 명시해 주어야 한다.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
numbers.Add(8);
numbers.Remove(3);
}
}
2. Dictionary<TKey, TValue>
- 키 - 값 (key - value) 형식으로 데이터를 저장하는 자료구조이다.
- Hashtable과의 차이점은 Generic을 활용하여 객체를 생성하고 생성한 타입과 일치하는 타입만 데이터로 저장할 수 있다.
- HashTable은 여러 타입을 활용 할 수 있다는 장점, Dictionary는 박싱과 언박싱이 없기 때문에 안정성과 속도가 빠르다는 장점이 있다.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> howOld = new Dictionary<string, int>();
ages["Kim"] = 30;
ages["Lee"] = 25;
ages["Park"] = 40;
}
}
3. Queue<T>, Stack<T>
- Queue와 Stack은 LIFO(Last-In-First-Out) 방식, FIFO(First-In-First-Out) 방식을 사용한다는 자료구조임은 동일하다.
- 다만 Queue와 Stack을 선언할때 사용할 자료형을 미리 명시해줘야 한다.
- ex) Queue<string> queue = new Queue<string>();
- ex) Stack<int> stack = new Stack<int>();
4. HashSet<T>
- 고유한 요소들을 저장하는 컬렉션으로, 중복된 데이터를 허용하지 않는다.
- 데이터의 존재 여부를 빠르게 검사할 수 있다.
- 데이터의 순서가 보장되지 않아서 순서가 중요한 데이터의 경우 다른 자료구조를 사용해야 한다.
- 집합 연산과 관련된 기능들을 수행할 수 있다.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
HashSet<int> numbers = new HashSet<int>();
// 요소 추가
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);
numbers.Add(1); // 중복 요소는 무시됨
// 요소 확인
Console.WriteLine(numbers.Contains(2));
Console.WriteLine(numbers.Contains(4));
// 요소 제거
numbers.Remove(2);
}
}
아래는 각종 집합 관련 연산을 수행하는 코드이다.
- UnionWith(); 는 합집합을 반환한다.
- IntetsectWith(); 는 교집합을 반환한다.
- ExceptWith(); 는 차집합을 반환한다.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
HashSet<int> set1 = new HashSet<int>() { 1, 2, 3, 4 };
HashSet<int> set2 = new HashSet<int>() { 3, 4, 5, 6 };
// 합집합
set1.UnionWith(set2);
Console.WriteLine("Union: " + string.Join(", ", set1)); // 1, 2, 3, 4, 5, 6
// 교집합
set1.IntersectWith(set2);
Console.WriteLine("Intersection: " + string.Join(", ", set1)); // 3, 4
// 차집합
set1.ExceptWith(set2);
Console.WriteLine("Difference: " + string.Join(", ", set1)); // 1, 2
}
}
정리
- using은 네임스페이스를 가져다 쓸때 사용한다.
- using System; 은 System 네임스페이스에서 지원하는 여러 클래스나 형식을 가져다 쓴다는 뜻이다.
- Collections과 Generic Collection은 자료구조의 형태가 비 제너릭과 제네릭이라는 차이점이 있다.
- 비 제너릭 클래스는 데이터 타입을 명시하지 않아도 되서 편리하지만 박싱과 언박싱 과정에서 성능 저하와 데이터 타입 관련 캐스팅 오류가 발생할 확률이 높다.
- 제네릭 클래스는 타입 안정성이 확보되며 성능이 올라간다. (일반적으로 제네릭을 많이 사용하게 된다.)
728x90
반응형
'C#' 카테고리의 다른 글
C# - 라이브러리 vs 프레임워크 (2) | 2024.07.11 |
---|---|
C# - Struct 와 Class의 차이점 (0) | 2024.06.21 |
C# - 스레드(Thread) (1) | 2024.06.18 |
C# - 동기와 비동기 (Synchronous/Asynchronous) (0) | 2024.06.13 |
C# - 가비지 컬렉션(Garbage Collection) (0) | 2024.06.07 |