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 |