개발꿈나무
[C# 교과서] 11. C# 활용(5) - 제네릭 사용하기 본문
제네릭 사용하기
- 제네릭 컬렉션은 특정 형식을 지정하여 컬렉션에 저장하고 사용하는 컬렉션이다.
- 기존의 컬렉션은 object 형식을 기준으로 데이터를 저장하고 사용하므로 메로리 낭비가 심한 반면 제네릭 컬렉션은 특정 형식을 지정하기 때문에 메모리 낭비가 없다.
- System.Collections.Generik 네임스페이스에 들어있는 제네릭 컬렉션 클래스는 요소를 다룰 때 데이터 형식 변환 등 작업이 따로 필요없다.
Cup of T
제네릭이란 넘어오는 데이터 형식에 따라 해당 개체 성격을 변경하는 구조
제네릭을 사용하면 여러 목적의 컬렉션 형식을 만들 수 있음
Stack 제네릭 클래스 사용하기
Stack 클래스의 제네릭 버전은 Stack<T> 형태로 표현하며 T는 특정 형식을 받아들이는 형식 매개변수이다.
using System;
using System.Collections.Generic;
class StackOfType
{
static void Main()
{
Stack<string> stack = new Stack<string>();
stack.Push("First"); // Push() 메서드는 문자열만 입력 가능
Console.WriteLine(stack.Pop()); // 문자열로 바로 출력
}
}
일반 클래스인 Stack과 제네릭 클래스인 Stack<T>는 하는 일은 동일하지만 Stack 클래스는 데이터를 object로 다루고 Stack<T> 클래스는 T로 지정한 데이터를 다룬다.
Stack 클래스에서는 object로 만든 데이터를 실제 사용하려는 변수(int, string, ...) 형식으로 표현하기 위해 중간 변환 과정을 거쳐야 하지만, Stack<T> 클래스는 정확한 데이터 형식을 사용할 수 있기 때문에 비용 절감 효과가 있다.
List<T> 제네릭 클래스 사용하기
List 클래스의 제네릭 버전은 List<T> 형태로 표현하며 T는 특정 형식을 받아들이는 형식 매개변수이다.
using System;
using System.Collections.Generic;
class ListOfInt
{
static void Main()
{
List<int> lstNumbers = new List<int>();
lstNumbers.Add(30);
lstNumbers.Add(40);
for (int i = 0; i < lstNumbers.Count; i++)
{
Console.WriteLine(lstNumbers[i]); // 30, 40
}
}
}
제네릭 클래스에서 T의 형식과 맞지 않는 데이터를 입력하면 오류가 발생한다.
(EX) 위의 코드에서 lstNumbers.Add("hi");를 입력하면 List는 int형인에 입력한 데이터는 string이라 오류 발생
Enumerable 클래스로 컬렉션 만들기
System.Linq 네임스페이스에 들어있는 Enumerable 클래스는 Range()와 Repeat() 메서드를 제공하므로 특정 범위의 정수 컬렉션을 손쉽게 만들 수 있다.
using System;
using System.Linq;
class EnumerableDemo
{
static void Main()
{
// 1부터 5개 (1 ~ 5)
var numbers = Enumerable.Range(1, 5);
foreach (var n in numbers)
Console.Write("{0}\t", n);
Console.WriteLine(); //1 2 3 4 5
// -1을 5개
var sameNumbers = Enumerable.Repeat(-1, 5);
foreach (var n in sameNumbers)
Console.Write("{0}\t", n);
Console.WriteLine(); //-1 -1 -1 -1 -1
}
}
Enumerable 클래스로 메서드 체인 방식의 코드도 작성할 수 있다.
Enumerable.Range(1, 100).Where(i => i % 2 == 0).Reverse().Skip(10).Take(5)
//8-, 78, 76, 74, 72
위의 코드는 1부터 100개 즉, 1부터 100까지의 숫자 중 짝수만 골라 역순으로 정렬하고, 정렬된 수에서 앞부터 10개를 건너뛴 후 5개만 가져오겠다는 코드이다.
Dictionary<T, T> 제네릭 클래스 사용하기
키와 값으로 데이터를 저장하고 사용하는 Dictionary 클래스도 데이터 형식을 지정하여 제네릭 클래스로 사용할 수 있다.
using System;
using System.Collections.Generic;
class DictionaryGenericClassDemo
{
static void Main()
{
//[1] Dictionary 클래스의 인스턴스 생성: IDictionary 인터페이스로 받기
IDictionary<string, string> data = new Dictionary<string, string>();
//[2] 데이터 입력
data.Add("cs", "C#");
data.Add("aspx", "ASP.NET");
//[3] 데이터 삭제
data.Remove("aspx");
//[4] 인덱서를 사용해서 데이터 입력
data["cshtml"] = "ASP.NET MVC";
//[5] 키 값 중복 불가: 에러 발생
try
{
data.Add("cs", "CSharp");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//[6] 출력: foreach (var item in data)로 줄여 표현 가능
foreach (KeyValuePair<string, string> item in data)
{
Console.WriteLine("{0}은(는) {1}의 확장자입니다.", item.Key, item.Value);
}
//[7] 인덱서를 사용해서 출력 가능
Console.WriteLine(data["cs"]);
//[8] 없는 키 요청: 에러 발생
try
{
Console.WriteLine(data["vb"]);
}
catch (KeyNotFoundException knfe)
{
Console.WriteLine(knfe.Message);
}
//[9] cs 키가 있으면 csharp 변수에 담아서 출력
if (data.TryGetValue("cs", out var csharp))
{
Console.WriteLine(csharp);
}
else
{
Console.WriteLine("cs 키가 없습니다.");
}
//[10] 키 값이 없으면 입력하고 출력
if (!data.ContainsKey("json"))
{
data.Add("json", "JSON");
Console.WriteLine(data["json"]);
}
//[11] Value 값을 따로 뽑아서 출력
var values = data.Values;
foreach (string item in values)
{
Console.WriteLine(item);
}
//[12] Key 값을 따로 뽑아서 출력
var keys = data.Keys;
foreach (string item in keys)
{
Console.WriteLine(item);
}
}
}
<Reference>
'C# > C#' 카테고리의 다른 글
[C#] 특정 날짜의 주 가져오기 (GetWeekOfYear) (0) | 2022.01.19 |
---|---|
XML data 읽어 xml 형식으로 뿌리기 (0) | 2021.10.18 |
[ASP.NET] MODEL에 여러 스키마의 DB 테이블 추가하기 (0) | 2021.09.16 |
[ASP.NET] InvalidCastException: 열에 널 데이터가 있습니다. (0) | 2021.09.16 |
[ASP.Net] Mornitoring Tool (0) | 2021.09.08 |