250x250
기리도
기리도의 개발새발 개발 일지
기리도
전체 방문자
오늘
어제
  • 분류 전체보기 (44)
    • Unity (6)
      • 모듈식 프로그래밍 (1)
    • C# (10)
    • 자료구조,알고리즘 (2)
    • 운영체제 (10)
      • 공룡책 (3)
      • 그림으로 쉽게 배우는 운영체제(인프런 강의) (7)
    • 리팩토링 (1)
    • 네트워크 (13)
      • 네트워크 장비 (13)
    • C, C++ 문법 (1)
      • 기타 (0)
      • C (1)
      • C++ (0)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 공부
  • 네트워크
  • 게임개발
  • 브릿지
  • 스위치
  • 길찾기
  • 탄환
  • 프로그래밍
  • 통신
  • 개발
  • 인프런
  • OS
  • C#
  • Unity
  • 유니티
  • 네트워크 게임
  • 운영체제
  • 개발공부
  • 네트워킹
  • 알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
기리도

기리도의 개발새발 개발 일지

제네릭(Generics)이란?
C#

제네릭(Generics)이란?

2022. 6. 24. 14:07
728x90

📕제네릭(Generics)이란?


📖제네릭이란?

제네릭이란 구체적인 데이터 형식이 정해지지 않은 형식으로, 클래스와 인터페이스, 추상 클래스, 필드, 메서드, 정적 메서드, 프로퍼티, 이벤트, 델리게이트에서 사용될 수 있다.

데이터 형식이 정해지지 않았기 때문에 제네릭 형식을 사용할 땐 데이터 형식이 들어갈 자리를 표시해 줘야 하는데, 이를 형식 매개 변수라고 한다.  형식 매개 변수의 이름은 정해진 바가 없으나 일반적으로 타입의 첫 글자인 T를 사용한다.

제네릭 형식을 선언하는 방법은 다음과 같다.

class DataStore<T>
{
    public T Data { get; set; }
}

위 코드에서 DataSotre는 제네릭 클래스이며 T는 형식 매개 변수다. Data는 구체적인 데이터 형식 대신 T를 사용해 선언되었으므로 제네릭 프로퍼티다.

class KeyValuePair<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}

형식 매개 변수가 여러 개일 때는 위처럼 콤마를 사용해 나타낼 수 있다.

💡형식 매개 변수가 하나뿐일 때는 T만 써도 충분하지만 매개 변수가 여러 개라면 가독성을 고려해 이름을 지어야 한다.

📌형식 매개 변수 제약

제네릭 형식에서 형식 매개 변수의 범주를 제한하고 싶다면 where 키워드를 사용하면 된다. 구체적인 형식은 다음과 같다.

GenericTypeName<T> where T  : constraint1, constraint2

where T : constraint1, constraint2의 의미는 constraint1, constraint2 형식만 T가 될 수 있도록 제한한다는 의미이다.

class DataStore<T> where T : class
{
    public T Data { get; set; }
}

마찬가지로 위 코드에서 where T : class는 class 형식만 T가 될 수 있도록 제한한다는 의미이다. 이때 제약 조건 class는 멤버로 구성된 데이터 구조가 아니라 참조 형식 전체이다. 즉, 참조 형식인 string과 delegate 등도 포함된다.

 

📖제네릭의 사용

📌제네릭의 장점

제네릭을 사용했을 때의 장점은 크게 세 가지이다.

  1. 코드의 재사용성을 높인다. 같은 동작을 수행하는데 데이터 형식만 다르다면 제네릭을 사용해 서로 다른 데이터 형식을 처리할 수 있다.
  2. 제약 조건에 맞지 않는 매개 변수를 사용할 경우 컴파일 오류가 발생하므로 안전하다.
  3. 형변환이 발생하지 않으므로 성능 낭비를 줄일 수 있다.

📌제네릭 클래스

제네릭 클래스를 사용하려면 new 키워드로 객체를 생성해야 한다.

DataStore<string> store = new DataStore<string>();

store라는 이름으로 위에서 정의한 DataStore 클래스의 객체를 생성했다. 형식 매개 변수는 string으로 지정했다. 따라서 DataStore 클래스의 모든 T는 string 형식이 된다.

다음으로는 Data 프로퍼티에 값을 할당해 주었다.

DataStore<string> store = new DataStore<string>();
store.Data = "Hello World!";
//store.Data = 123; //compile-time error

stroe.Data = "Hello World!";의 경우 Data의 형식과 "Hello World!"의 형식이 일치하므로  정상적으로 작동한다. 반면 주석 처리 된 store.Data = 123;를 실행하면 컴파일 오류가 발생한다.

📌제네릭 필드

제네릭으로 선언한 필드는 초기화할 수 없다.

class DataStore<T>
{
    public T data;
}

배열은 다음과 같이 사용한다.

class DataStore<T>
{
    public T[] data = new T[10];
}

📌제네릭 메서드 in generic Class

class DataStore<T>
{
    private T[] _data = new T[10];
    
    public void AddOrUpdate(int index, T item)
    {
        if(index >= 0 && index < 10)
            _data[index] = item;
    }

    public T GetData(int index)
    {
        if(index >= 0 && index < 10)
            return _data[index];
        else 
            return default(T);
    }
}

위 코드에는 제네릭 메서드 AddOrUpdate와 GetData가 정의되어 있다. AddOrUpdate는 반환 형식은 없고 매개 변수 형식은 int와 T이다. GetData는 반환 형식이 T이고 매개 변수 형식은 int이다. 두 메서드의 T는 DataStore<T> 클래스가 생성될 때 정해진다.

DataStore<string> cities = new DataStore<string>();
cities.AddOrUpdate(0, "Mumbai");
cities.AddOrUpdate(1, "Chicago");
cities.AddOrUpdate(2, "London");

DataStore<int> empIds = new DataStore<int>();
empIds.AddOrUpdate(0, 50);
empIds.AddOrUpdate(1, 65);
empIds.AddOrUpdate(2, 89);

📌제네릭 메서드 in Non-generic Class

class Printer
{
    public void Print<T>(T data)
    {
        Console.WriteLine(data);
    }
}

Printer printer = new Printer();
printer.Print<int>(100);
printer.Print(200); // type infer from the specified value
printer.Print<string>("Hello");
printer.Print("World!"); // type infer from the specified value

제네릭 클래스가 아닌 클래스에서 제네릭 메서드를 정의할 땐 메서드 이름 옆에 <T>를 추가한다.


🔖인용 및 참고

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-type-parameters#type-parameter-naming-guidelines

 

Generic Type Parameters - C# Programming Guide

Learn about generic type definition in C#, where a type parameter is a placeholder for a type that a client specifies for an instance of the generic type.

docs.microsoft.com

https://www.tutorialsteacher.com/csharp/constraints-in-generic-csharp

 

C# Generic Constraints

C# Generic Constraints C# allows you to use constraints to restrict client code to specify certain types while instantiating generic types. It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the s

www.tutorialsteacher.com

https://www.tutorialsteacher.com/csharp/csharp-generics

 

C# Generics

C# Generics Generic means the general form, not specific. In C#, generic means not specific to a particular data type. C# allows you to define generic classes, interfaces, abstract classes, fields, methods, static methods, properties, events, delegates, an

www.tutorialsteacher.com

728x90
저작자표시 (새창열림)

'C#' 카테고리의 다른 글

[C#] 딕셔너리(Dictionary)  (0) 2022.07.08
[C#]리플렉션(Reflection)과 어트리뷰트(Attribute)  (0) 2022.07.06
구조체(Struct)와 클래스(Class)  (0) 2022.06.17
생성자  (0) 2022.06.17
프로퍼티(Property, 속성)  (0) 2022.06.14
    'C#' 카테고리의 다른 글
    • [C#] 딕셔너리(Dictionary)
    • [C#]리플렉션(Reflection)과 어트리뷰트(Attribute)
    • 구조체(Struct)와 클래스(Class)
    • 생성자
    기리도
    기리도
    공부한 내용을 정리해서 올리는 블로그입니다.

    티스토리툴바