posted by 방랑군 2012. 1. 4. 13:18

출처 : http://kimstar.pe.kr/blog/100?category=18

1) 박싱 & 언박싱
   - 값타입 --박싱--> 참조타입
   - 참조타입 --언박싱--> 값타입
  
  ArrayList al = new ArrayList();
  al.Add(100);                        // ArrayList는 object를 저장함. 따라서 100(값타입)은 참조타입으로 box되어 저장됨
  int val = (int)al[0];               // al[0]를 int(값타입)로 사용하기 위해 unboxing됨

2) 값타입
   - 단순타입 : int, byte, char, float, decimal, bool 등
  - 열거형타입 : enum
  - 구조체타입 : struct
  - nullable 타입 : int?, double? 등

3) 참조타입
  - 클래스 타입 : object, string, class
  - 인터페이스 타입 : interface
  - 배열타입 : Array(int[], int[,] 등)
  - 델리게이트 타입 : delegate

4) Generic
   - boxing, unboxing 에 사용되는 리소스 소비 해결
  - Generic에 사용되는 타입은 일반적으로 T로 명명

  List<int> list = new List<int>();  // int 타입을 제네릭 타입 파라메터로 지정
  list.Add(100);                     // int 데이타만 저장가능
  int val2 = list[0];                // int 타입이기에 형변환 필요없음

5) Generic 제한사항
   - 제네릭 적용 클래스는 ContextBoundObject 클래스로 파생될 수 없음 : 런타임 오류발생
  - 제네릭은 열거형에 사용못함
  - 제네릭은 Reflection을 이용해 생성되는 동적메소드에 사용못함.

6) Generic 제약사항
   - 제네릭이 클래스레벨에서 지정될때 where로 제약을 지정할 수 있음

7) .Net Framework에서 제공하는 Generic
   - Dictionary<TKey, TValue> : Hashtable의 제네릭 버전. Key & Value가 한쌍. Key는 유일
  - List<T> : ArrayList의 제네릭 버전. 배열의 크기를 동적으로 구성
   - SortedList<TKey, TValue> : Dictionary + List. Key & Value가 한쌍. 동적 배열. Key값으로 정렬됨.
  - LinkedList<T> : 새로생김.
  - Queue<T> : Queue의 제네릭 버전
  - Stack<T> : Stack의 제네릭 버전

타입 제네릭 비제네릭 제네릭 네임스페이스
클래스 List<T> ArrayList System.Collections.Generic
Dictonary<TKey, TValue> HashTable
SortedList<TKey, TValue> SortedList
Stack<T> Stack
Queue<T> Queue
LinkedList<T> -
ReadOnlyCollection<T> - System.Collections.ObjectModel
KeyedCollection<TKey, TValue> -
인터페이스 IList<T> IList System.Collections.Generic
IDictonary<TKey, TValue> IDictonary
ICollection<T> ICollection
IEumerator<T> IEumerator
IEumerable<T> IEumerable
IComparer<T> IComparer
IComparable<T> IComparable




001.using System;
002.using System.Collections;
003.using System.Collections.Generic;
004. 
005.namespace GenericTest
006.{
007.class Program
008.{
009.static void Main(string[] args)
010.{
011.// 박싱 & 언박싱------------------
012.// boxing & unboxing 발생함
013.ArrayList al = new ArrayList();
014.al.Add(1);                         // ArrayList는 object를 저장함. 따라서 100(값타입)은 참조타입으로 box되어 저장됨
015.intval = (int)al[0];              // al[0]를 int(값타입)로 사용하기 위해 unboxing됨
016.Console.WriteLine(val);
017. 
018.// boxing & unboxing 발생 안함
019.List<int> list = newList<int>();  // int 타입을 제네릭 타입 파라메터로 지정
020.list.Add(2);                       // int 데이타만 저장가능
021.int val2 = list[0];                // int 타입이기에 형변환 필요없음
022.Console.WriteLine(val2);
023. 
024. 
025.// 제네릭 선언------------------
026.// class를 제네릭으로 선언
027.GenericDeclare1<int> gd = new GenericDeclare1<int>();
028.gd.GenericProperty = 3;
029.Console.WriteLine(gd.GenericProperty);
030. 
031.// method를 제네릭으로 선언
032.GenericDeclare2 gd2 = new GenericDeclare2();
033.Console.WriteLine(gd2.GenericMethod<int>(4));
034. 
035. 
036.// class를 제네릭으로 선언 - where 제약------------------
037.//GC1<int> gc1 = new GC1<int>();  --> 오류발생 : int는 IDispose를 구현한 놈이 아님
038.GC1<TestGC1> gc1 = new GC1<TestGC1>();
039. 
040.//GC2<int, string> gc2 = new GC2<int, string>(); --> 오류발생 : int/string은 class/struct가 아님
041.GC2<TestGC2Class, TestGC2Strunct> gc2 = newGC2<TestGC2Class, TestGC2Strunct>();
042. 
043.//GC3<int> gc3 = new GC3<int>(); --> 오류발생 : int는 어쨓든 아님
044.//GC3<TestGC3_1> gc3 = new GC3<TestGC3_1>();  --> 오류발생 : TestGC3_1 은 IDispose를 구현했지만, 생성자에 파라메터가 있음
045.GC3<TestGC3_2> gc3 = new GC3<TestGC3_2>();
046. 
047.// TODO : 이거 잘 모르겠다.. 나중에 수정하자
048.GC4 gc4 = new GC4();
049.}
050.}
051. 
052. 
053. 
054.#region 테스트용 클래스들
055. 
056.class TestGC1 : IDisposable
057.{
058.public void Dispose()
059.{
060.}
061.}
062. 
063.class TestGC2Class
064.{
065.}
066. 
067.struct TestGC2Strunct
068.{
069.}
070. 
071.class TestGC3_1 : IDisposable
072.{
073.public TestGC3_1(int i)
074.{
075.}
076. 
077.public void Dispose()
078.{
079.}
080.}
081. 
082.class TestGC3_2 : IDisposable
083.{
084.public TestGC3_2()
085.{
086.}
087. 
088.public void Dispose()
089.{
090.}
091.}
092.#endregion
093. 
094. 
095. 
096./// <summary>
097./// class를 제네릭으로 선언
098./// </summary>
099.class GenericDeclare1<T1>
100.{
101.private T1 val;
102. 
103.public T1 GenericProperty
104.{
105.get { return val; }
106.set { this.val = value; }
107.}
108.}
109. 
110.class GenericDeclare2
111.{
112./// <summary>
113./// 메소드를 제네릭으로 선언
114./// </summary>
115.public T2 GenericMethod<T2>(T2 arg)
116.{
117.return arg;
118.}
119.}
120. 
121. 
122. 
123. 
124.#region Class를 제네릭으로 구현시 where로 제약하는 예제
125./// <summary>
126./// T는 IDisposable 인터페이스를 구현해야함
127./// </summary>
128.class GC1<T>
129.where T : IDisposable
130.{
131.}
132. 
133./// <summary>
134./// T는 클래스여야함
135./// U는 구조체여야함
136./// </summary>
137.class GC2<T, U>
138.where T : class
139.where U : struct
140.{
141.}
142. 
143./// <summary>
144./// T는 IComparable을 구현해야하고
145./// 파라메터가 없는 - "new()" - 기본 생성자를 가진 T 이다
146./// </summary>
147.class GC3<T>
148.where T : IDisposable, new()
149.{
150.}
151. 
152./// <summary>
153./// 델리게이트에 파라미터가 없는 - "new()" - 기본생성자를 가진 T
154./// </summary>
155.class GC4
156.{
157.delegate T GenericDelegate<T>(T val) where T : new();
158.//delegate int GenericDelegate2(int val);
159.}
160.#endregion
161.}