제너릭 프로그래밍
장점은 하단에..
제네릭 메소드와 클래스 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | using System; namespace GenericEx { class ClassA { public static void CopyArray(int[] src, int[] target) { for (int i = 0; i < src.Length; ++i) { target[i] = src[i]; } } public static void CopyArray(string[] src, string[] target) { for (int i = 0; i < src.Length; ++i) { target[i] = src[i]; } } // 제네릭 메소드 public static void GenericCopyArray<T>(T[] src, T[] target) { for (int i = 0; i < src.Length; ++i) { target[i] = src[i]; } } } // 제네릭 클래스 class GenericClassA<T> { public static void GenericCopyArray(T[] src, T[] target) { for (int i = 0; i < src.Length; ++i) { target[i] = src[i]; } } } class MainClass { public static void Main (string[] args) { int[] iSrc = { 1, 2, 3, 4, 5 }; int[] iTarget = new int[5]; string[] strSrc = { "ab", "cd", "ef", "gh", "ij" }; string[] strTarget = new string[5]; ClassA.CopyArray(iSrc, iTarget); foreach (int i in iTarget) Console.WriteLine(i); ClassA.CopyArray(strSrc, strTarget); foreach (string s in strTarget) Console.WriteLine(s); float[] fSrc = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f }; float[] fTarget = new float[5]; // 제네릭 메소드의 활용 ClassA.GenericCopyArray<float>(fSrc, fTarget); foreach (float f in fTarget) Console.WriteLine(f); // 제네릭 클래스의 활용 GenericClassA<float>.GenericCopyArray(fSrc, fTarget); foreach (float f in fTarget) Console.WriteLine(f); Console.ReadKey(); } } } | cs |
LinkedList<T> 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | using System; using System.Text; using System.Collections.Generic; namespace LinkedListTEx { class MainClass { private static void Display(LinkedList<string> words, string test) { Console.WriteLine(test); foreach (string word in words) { Console.Write(word + " "); } Console.WriteLine(); Console.WriteLine(); } private static void IndicateNode(LinkedListNode<string> node, string test) { Console.WriteLine(test); if (node.List == null) { Console.WriteLine("Node '{0}' is not in the list.\n", node.Value); return; } StringBuilder result = new StringBuilder("(" + node.Value + ")"); LinkedListNode<string> nodeP = node.Previous; while (nodeP != null) { result.Insert(0, nodeP.Value + " "); nodeP = nodeP.Previous; } node = node.Next; while (node != null) { result.Append(" " + node.Value); node = node.Next; } Console.WriteLine(result); Console.WriteLine(); } public static void Main (string[] args) { string[] words = { "유니티", "C#으로", "스크립팅", "한다"}; // 연결 리스트의 생성 LinkedList<string> sentence = new LinkedList<string>(words); Display(sentence, "연결 리스트의 값은:"); Console.WriteLine("sentence.Contains(\"유니티\") = {0}", sentence.Contains("유니티")); sentence.AddFirst("오늘은"); Display(sentence, "Test 1: 리스트 앞에 '오늘은' 문자열 추가"); LinkedListNode<string> mark1 = sentence.First; sentence.RemoveFirst(); sentence.AddLast(mark1); Display(sentence, "Test 2: 마지막 단어를 끝으로 이동"); sentence.RemoveLast(); sentence.AddLast("오늘만"); Display(sentence, "Test 3: 마지막 단어를 '오늘만' 으로 변경"); mark1 = sentence.Last; sentence.RemoveLast(); sentence.AddFirst(mark1); Display(sentence, "Test 4: 마지막 노드를 첫 노드로 이동"); sentence.RemoveFirst(); LinkedListNode<string> current = sentence.FindLast("C#으로"); IndicateNode(current, "Test 5: '스크립팅'이라는 단어를 찾아 가리킨다 "); sentence.AddAfter(current, "자바스크립트로"); sentence.AddAfter(current, "그리고"); IndicateNode(current, "Test 6: '스크립팅' 단어 뒤에 단어 추가"); current = sentence.Find("유니티"); IndicateNode(current, "Test 7: '유니티' 노드를 가리킨다"); sentence.AddBefore(current, "오늘과"); sentence.AddBefore(current, "내일은"); IndicateNode(current, "Test 8: '오늘과', '내일은' 단어를 '유니티' 노드 앞에 추가"); } } } | cs |
List<T> 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | using System; using System.Collections.Generic; namespace ListTEx { public class Enemy { public string Name { get; set; } public int Level { get; set; } public int HP { get; set; } public int Exp { get; set; } public void printEnemyInfo() { Console.WriteLine ("Name : {0} Level : {1} HP : {2} Exp : {3}", Name, Level, HP, Exp); } } class MainClass { public static List<Enemy> enemyList; public static void Main (string[] args) { enemyList = new List<Enemy>(); // 추가 enemyList.Add (new Enemy () { Name = "Slime", Level = 1, HP = 200, Exp = 30 }); enemyList.Add (new Enemy () { Name = "Zombie", Level = 2, HP = 100, Exp = 50 }); enemyList.Add (new Enemy () { Name = "Skeleton", Level = 3, HP = 120, Exp = 80 }); enemyList.Add (new Enemy () { Name = "Bugbear", Level = 4, HP = 300, Exp = 150 }); // 삽입 enemyList.Insert (2, new Enemy () { Name = "Bugbear", Level = 5, HP = 350, Exp = 180 }); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyList) { enemy.printEnemyInfo(); } // 삭제 enemyList.RemoveAt (2); // 검색 후 삭제 Enemy bugBear = enemyList.Find (x => x.Name.Equals ("Bugbear")); enemyList.Remove (bugBear); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyList) { enemy.printEnemyInfo(); } } } } | cs |
Dictionary<TKey, TValue> 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | using System; using System.Collections.Generic; namespace DictionaryTEx { public class FileFormatTable { private Dictionary<string, string> openWith; public FileFormatTable() { openWith = new Dictionary<string, string>(); // 추가 openWith.Add("txt", "notepad.exe"); openWith.Add("bmp", "paint.exe"); openWith.Add("dib", "paint.exe"); openWith.Add("rtf", "wordpad.exe"); openWith.Add("odf", "wordpad.exe"); // 이미 할당 된 키일 경우 try { openWith.Add("txt", "winword.exe"); } catch { Console.WriteLine("An element with Key = \"txt\" already exists."); } // 제거 openWith.Remove("odf"); } public void printTable() { // 탐색 foreach (KeyValuePair<string, string> d in openWith) Console.WriteLine("Key = {0}, Value = {1}", d.Key, d.Value); } } class MainClass { public static void Main (string[] args) { FileFormatTable fileFormatTable = new FileFormatTable (); fileFormatTable.printTable (); } } } | cs |
Queue<T> 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | using System; using System.Collections.Generic; namespace QueueTEx { public class Enemy { public string Name { get; set; } public int Level { get; set; } public int HP { get; set; } public int Exp { get; set; } public void printEnemyInfo() { Console.WriteLine ("Name : {0} Level : {1} HP : {2} Exp : {3}", Name, Level, HP, Exp); } } class MainClass { public static Queue<Enemy> enemyQueue; public static void Main (string[] args) { enemyQueue = new Queue<Enemy>(); // 추가 enemyQueue.Enqueue (new Enemy () { Name = "Slime", Level = 1, HP = 200, Exp = 30 }); enemyQueue.Enqueue (new Enemy () { Name = "Zombie", Level = 2, HP = 100, Exp = 50 }); enemyQueue.Enqueue (new Enemy () { Name = "Skeleton", Level = 3, HP = 120, Exp = 80 }); enemyQueue.Enqueue (new Enemy () { Name = "Bugbear", Level = 4, HP = 300, Exp = 150 }); enemyQueue.Enqueue (new Enemy () { Name = "Bugbear", Level = 5, HP = 350, Exp = 180 }); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyQueue) { enemy.printEnemyInfo(); } // 삭제 Console.WriteLine ("********* Out *********"); Enemy outEnemy = enemyQueue.Dequeue (); outEnemy.printEnemyInfo (); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyQueue) { enemy.printEnemyInfo(); } // 검색 후 삭제 Console.WriteLine ("******** First *********"); Enemy firstEnemy = enemyQueue.Peek(); firstEnemy.printEnemyInfo (); } } } | cs |
Stack<T> 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | using System; using System.Collections.Generic; namespace StackTEx { public class Enemy { public string Name { get; set; } public int Level { get; set; } public int HP { get; set; } public int Exp { get; set; } public void printEnemyInfo() { Console.WriteLine ("Name : {0} Level : {1} HP : {2} Exp : {3}", Name, Level, HP, Exp); } } class MainClass { public static Stack<Enemy> enemyStack; public static void Main (string[] args) { enemyStack = new Stack<Enemy>(); // 추가 enemyStack.Push (new Enemy () { Name = "Slime", Level = 1, HP = 200, Exp = 30 }); enemyStack.Push (new Enemy () { Name = "Zombie", Level = 2, HP = 100, Exp = 50 }); enemyStack.Push (new Enemy () { Name = "Skeleton", Level = 3, HP = 120, Exp = 80 }); enemyStack.Push (new Enemy () { Name = "Bugbear", Level = 4, HP = 300, Exp = 150 }); enemyStack.Push (new Enemy () { Name = "Bugbear", Level = 5, HP = 350, Exp = 180 }); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyStack) { enemy.printEnemyInfo(); } // 삭제 Console.WriteLine ("********* Out *********"); Enemy outEnemy = enemyStack.Pop (); outEnemy.printEnemyInfo (); Console.WriteLine ("**********************"); foreach (Enemy enemy in enemyStack) { enemy.printEnemyInfo(); } // 검색 후 삭제 Console.WriteLine ("******** Last *********"); Enemy lastEnemy = enemyStack.Peek(); lastEnemy.printEnemyInfo (); } } } | cs |
출처: http://codepump.tistory.com/56 [CodePump.NET]
제네릭의 장점
제네릭을 사용하면 이전 버전의 공용 언어 런타임과 C# 언어에 적용되었던 제한 사항을 해결할 수 있습니다. 이전 버전에서는 유니버설 기본 형식인
제네릭이 아닌 컬렉션 클래스를 사용하는 경우의 제한 사항을 보여 주는 예로는 .NET Framework 클래스 라이브러리에서
// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);
System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");
그러나 이러한 편리함에는 상응하는 대가가 따릅니다.
다른 제한 사항으로는 컴파일 타임에 형식을 검사할 수 없다는 점을 들 수 있습니다.
System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");
int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
t += x;
}
유형이 다른 컬렉션을 만드는 경우 규칙을 정확히 따르는 의도적인 선택일지라도 문자열과 ints를 단일
버전 1.0 및 1.1의 C# 언어에서는 고유한 형식별 컬렉션을 작성하는 방법으로만 .NET Framework 기본 클래스 라이브러리 컬렉션 클래스에서 코드를 일반화하는 위험을 방지할 수 있었습니다. 물론 이러한 클래스는 여러 데이터 형식에 다시 사용할 수 없으므로 일반화의 이점이 사라지고 저장하려는 각 형식에 대해 클래스를 다시 작성해야만 합니다.
// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();
// No boxing, no casting:
list1.Add(3);
// Compile-time error:
// list1.Add("It is raining in Redmond.");
'프로그래밍(Programming) > C#' 카테고리의 다른 글
String 문자열(C# 프로그래밍 가이드) (0) | 2017.09.18 |
---|---|
제네릭 Collection(컬렉션) 개체 (0) | 2017.09.08 |
using 과 Dispose() (0) | 2017.07.19 |
확장메서드 public static class (0) | 2017.07.18 |
프로퍼티 value (0) | 2015.11.17 |