08
18

C# 제네릭(C# Generics)

일반적으로 클래스를 정의할 때, 클래스 내의 모든 데이터 타입을 지정해 주게 된다. 하지만. 어떤 경우는 클래스의 거의 모든 부분이 동일한데 일부 데이터 타입만이 다른 경우가 있을 수 있다. 이런 경우 C#의 제네릭 타입(Generic Type)을 사용할 수 있는데, 제네릭 타입에서는 int, float, double 같은 데이터 요소 타입을 확정하지 않고 이 데이터 타입 자체를 타입 파라미터(Type Parameter)로 받아들이도록 클래스를 정의한다. C# 제네릭 타입을 사용할 때는 클래스명과 함께 구체적인 데이터 타입을 함께 지정해 주게 된다. C# 제네릭은 이렇게 클래스 이외에도 인터페이스나 메서드에도 적용될 수 있다. 클래서, 인터페이스, 메서드 등에 <T> 같은 타입 파라미터를 붙여 구현한다. 사용 시에는 이 타입 파라미터에 특정 타입을 지정하게 되는데, 실행 시에 제네릭 타입으로부터 지정된 타입의 객체를 구체적으로 생성해서 사용하게 된다.

 

제네릭 타입 제약(Type Constraint)

C# 제네릭 타입을 선언할 때, 타입 파라미터가 Value Type인지 Reference Type인지, 또는 어떤 특정 Base 클래스로부터 파생된 타입인지, 어떤 인터페이스를 구현한 타입인지 등을 지정할 수 있는데, 이는 where T : 제약조건과 같은 식으로 where 뒤에 제약 조건을 붙이면 가능하다.

 

// T는 Value 타입
class MyClass<T> where T : struct
{
}

// T는 Reference 타입
class MyCalss<T> where T : class
{
}

// T는 디폴트 생성자를 가져야 함
class MyClass<T> where T : new()
{
}

// T는 MyBase의 파생클래스이어야 함
class MyClass<T> where T : MyBase()
{
}

// T는 IComparable 인터페이스를 가져야 함
class MyClass<T> where T : IComparable
{
}

// 좀 더 복잡한 제약들
class EmployeeList<T> where T : Employee, IEmployee, IComparable<T>, new()
{
}

// 복수 타입 파라미터 제약
class MyCalss<T,U> where T : class
                   where U : struct
{
}

 

ex)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class Program
{
    static void ArrayPrint<T>(T[] Num)
    {
        for (int i = 0; i < Num.Length; i++)
        {
            Console.Write($"{Num[i]} ");
        }
        Console.WriteLine();
    }

    static void Main(string[] args)
    {
        int[] Numbers1 = { 1, 3, 5, 7, 9 };
        double[] Numbers2 = { 1.1, 3.1, 5.1, 7.1, 9.1 };
        string[] Numbers3 = { "일", "이" };

        ArrayPrint<int>(Numbers1);
        ArrayPrint<double>(Numbers2);
        ArrayPrint<string>(Numbers3);
    }
}

 

예제 실행 화면

 

using System;


class Fact<T1, T2>
{
    public T1 Value1;
    public T2 Value2;

    public void Print()
    {
        Console.WriteLine($"FACT Value1 = {Value1}, Value2 = {Value2}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Fact<int, double> fact = new Fact<int,double>();
        fact.Value1 = 100;
        fact.Value2 = 1.1;
        fact.Print();

        Fact<string, string> fact1 = new Fact<string, string>();
        fact1.Value1 = "Test";
        fact1.Value2 = "class";
        fact1.Print();
    }
}

 

예제 실행 화면

 

using System;


class Fact<T1, T2>
{
    public T1 Value1;
    public T2 Value2;

    public void Print()
    {
        Console.WriteLine($"FACT Value1 = {Value1}, Value2 = {Value2}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Fact<int, double> fact = new Fact<int,double>();
        fact.Value1 = 100;
        fact.Value2 = 1.1;
        fact.Print();

        Fact<string, string> fact1 = new Fact<string, string>();
        fact1.Value1 = "Test";
        fact1.Value2 = "class";
        fact1.Print();
    }
}

 

예제 실행 화면

'스마트팩토리 > C#' 카테고리의 다른 글

30. Random 클래스  (0) 2020.08.20
29. 익명타입(Anonymous Type)  (0) 2020.08.19
27. 네트워크 통신  (0) 2020.07.29
26. 연산 범위 확인, 가변 매개변수, extern, unsafe  (0) 2020.07.27
25. MessageMap  (0) 2020.07.24
COMMENT