제네릭은 C# 버전 2.0에 추가되었으며 언어에서 가장 중요한 개념 중 하나입니다. 컴파일 타임에 형식이 안전한 재사용 가능한 고성능 코드를 작성할 수 있습니다. 제네릭을 사용하면 미리 알지 못하는 상태에서 코드에서 유형을 사용할 수 있습니다.
제네릭은 컬렉션, 대리자 및 비동기 코드를 포함하여 .NET의 여러 위치에서 사용됩니다. 제네릭을 사용하면 컬렉션의 크기를 미리 알 필요가 없으며 코드에 특정한 사용자 지정 데이터 형식을 포함하여 모든 요소 형식에 제네릭을 사용할 수 있습니다. C#은 제네릭 유형(클래스, 인터페이스 등)과 제네릭 메서드를 모두 지원합니다.
제네릭에는 형식 매개 변수와 형식 인수가 있습니다. 이는 매개변수가 있는 메소드와 유사하며 메소드에 인수를 전달합니다.
일반 유형
제네릭 형식을 선언하는 구문은 형식 이름 뒤의 꺾쇠 괄호 안에 있는 형식 매개 변수로 구성됩니다. 예를 들어, Locator
public class Locator<T> { }
Locator
var stringLocator = new Locator<string>();
아래 예와 같이 클래스 메서드에 유형 매개변수(T)를 사용할 수 있습니다.
public class Locator<T>{ public IList<T> Items { get; set; } public T Locate(int index){ return Items[index]; } } var stringLocator = new Locator<string>(); string item = stringLocator.Locate(2);
제네릭의 추가 이점은 편집기에서 제공하는 IntelliSense입니다. stringLocator.Locate(4)를 Visual Studio 또는 VS Code에 입력하고 메서드 이름 위로 마우스를 가져갈 때; T 대신 문자열을 반환한다는 것을 보여줍니다. 문자열이 아닌 다른 유형에 결과를 할당하려고 하면 컴파일러에서 오류가 발생합니다. 예를 들어,
// Error: Cannot implicitly convert type 'string' to 'int' [c-sharp]csharp(CS0029) int item = stringLocator.Locate(2);
제네릭 형식은 제네릭 기본 형식이나 제네릭 인터페이스에서 상속할 때 형식 매개 변수를 형식 인수로 사용할 수 있습니다. 일반 LinkedList
public class LinkedList<T> : IEnumerable<T>
일반 방법
제네릭 메서드는 메서드 내에서 그리고 매개변수 및 반환 형식으로 사용할 수 있는 형식 매개 변수를 선언하는 메서드입니다. 아래 예에서 Swap
public class Swapper{ public T Swap<T>(T first, T second){ T temp = first; first = second; second = temp; return temp; } }
제네릭 형식과 마찬가지로 제네릭 메서드를 호출하면 강력한 형식의 변수가 반환됩니다.
var swapper = new Swapper(); int result = swapper.Swap<int>(5, 3);
여러 개의 일반 매개변수를 가질 수 있습니다. System.Collections.Generic 네임스페이스의 Dictionary 클래스에는 키와 값의 두 가지 유형 매개변수가 있습니다.
public class Dictionary<TKey, TValue>
마지막으로 무엇이 일반적일 수 있는지 아는 것이 중요합니다. 열거형을 제외한 유형의 경우 모든 것이 제네릭일 수 있습니다. 여기에는 -
가 포함됩니다.- 수업
- 구조체
- 인터페이스
- 대리인
형식 멤버의 경우 메서드와 중첩 형식만 제네릭이 될 수 있습니다. 다음 멤버는 제네릭이 될 수 없습니다 -
- 필드
- 속성
- 인덱서
- 생성자
- 이벤트
- 결선자
예
using System; using System.Collections.Generic; class Program{ static void Main(){ var stringLocator = new Locator<string>(){ Items = new string[] { "JavaScript", "CSharp", "Golang" } }; string item = stringLocator.Locate(1); Console.WriteLine(item); // CSharp var swapper = new Swapper(); int a = 5, b = 3; int result = swapper.Swap<int>(ref a, ref b); Console.WriteLine($"a = {a}, b = {b}"); } } public class Locator<T>{ public IList<T> Items { get; set; } public T Locate(int index){ return Items[index]; } } public class Swapper{ public T Swap<T>(ref T first, ref T second){ T temp = first; first = second; second = temp; return temp; } }
출력
CSharp a = 3, b = 5