형식 매개변수(Type Parameter) 제약하기

00·2024년 12월 22일

C#

목록 보기
59/149

using System;

/*
형식 매개변수(Type Parameter)의 조건에 제약 걸기
: 일반화 메소드나 일반화 클래스가 입력받는 형식 매개변수 T는 '모든' 데이터 형식을 대신할 수 있다.
하지만 특정 조건을 갖춘 형식에만 대응하는 형식 매개변수가 필요할 때가 있다.
이럴 때 형식 매개변수의 조건에 제약을 걸 수 있다.

제약 조건의 종류?
(1) where T : struct: 값 형식(struct) 제약 조건
(2) where T : class: 참조 형식(class) 제약 조건
(3) where T : new(): 매개변수 없는 생성자 제약 조건
(4) where T : Base: 기본 클래스 제약 조건
(5) where T : U: 타입 매개변수 제약 조건

-> 제약 조건을 사용하면, 제네릭 타입 매개변수에 대한 제약을 설정하여
타입 안전성을 확보하고 코드의 유연성을 높일 수 있습니다.
*/

// 제네릭 타입 매개변수에 제약 조건을 설정하는 방법을 보여줍니다.
// 제네릭은 타입을 매개변수로 사용하여 코드를 재사용할 수 있도록 하는 기능입니다.
// 제약 조건은 제네릭 타입 매개변수에 대해 특정 조건을 지정하여
// 타입 안전성을 확보하고 코드의 유연성을 높입니다.
namespace ConstraintsOnTypeParameters
{
class StructArray where T : struct // 값 형식(struct)만 허용하는 제네릭 클래스 StructArray 입니다.
// T는 값 형식이어야 합니다.
{
public T[] Array { get; set; } // T 타입의 배열을 저장하는 프로퍼티입니다.
public StructArray(int size) // 생성자로,
{
Array = new T[size]; // size 크기의 T 타입 배열을 생성하여 Array 필드에 할당합니다.
}
}

class RefArray<T> where T : class // 참조 형식(class)만 허용하는 제네릭 클래스 RefArray<T> 입니다.
                                  // T는 참조 형식이어야 합니다.
{
    public T[] Array { get; set; } // T 타입의 배열을 저장하는 프로퍼티입니다.
    public RefArray(int size) // 생성자로, 
    {
        Array = new T[size]; // size 크기의 T 타입 배열을 생성합니다.
    }
}

class Base { }
class Derived : Base { }
class BaseArray<U> where U : Base // 제네릭 클래스 BaseArray<U>는 
                                  // U 타입 매개변수가 Base 클래스 또는 Base 클래스에서 파생된 클래스여야 함
{
    public U[] Array { get; set; } // U 타입의 배열을 저장하는 프로퍼티입니다.
    public BaseArray(int size) // 생성자로, 
    {
        Array = new U[size]; // size 크기의 U 타입 배열을 생성합니다.
    }

    public void CopyyArray<T>(T[] Target) where T : U // Target 배열의 요소를 Array 배열에 복사하는 제네릭 메서드입니다. 
                                                      // where T : U 제약 조건을 사용하여, 
                                                      // T 타입 매개변수가 U 타입 매개변수와 같거나 
                                                      // U 타입 매개변수에서 파생된 타입이어야 함을 지정합니다.

    {
        Target.CopyTo(Array, 0);
    }
}

class MainApp
{
    public static T CreateInstance<T>() where T : new() // T 타입의 객체를 생성하여 반환하는 메서드입니다. 
                                                        // where T : new() 제약 조건을 사용하여,
                                                        // T 타입 매개변수가 매개변수 없는 생성자를 가져야 함을 지정합니다.
    {
        return new T();
    }


    static void Main(string[] args)
    {
        
        StructArray<int> a = new StructArray<int>(3); 
        // int 타입의 StructArray 객체를 생성합니다.
        a.Array[0] = 0;
        a.Array[1] = 1;
        a.Array[2] = 2;


        RefArray<StructArray<double>> b = new RefArray<StructArray<double>>(3);
        // StructArray<double> 타입의 RefArray 객체를 생성합니다.
        b.Array[0] = new StructArray<double>(5);
        b.Array[1] = new StructArray<double>(10);
        b.Array[2] = new StructArray<double>(1005);


        BaseArray<Base> c = new BaseArray<Base>(3);
        // Base 타입의 BaseArray 객체를 생성합니다.
        c.Array[0] = new Base();
        c.Array[1] = new Derived();
        c.Array[2] = CreateInstance<Base>();


        BaseArray<Derived> d = new BaseArray<Derived>(3);
        // Derived 타입의 BaseArray 객체를 생성합니다.
        d.Array[0] = new Derived(); // Base 형식은 여기에 할당 할 수 없다.
        d.Array[1] = CreateInstance<Derived>();
        d.Array[2] = CreateInstance<Derived>();

        BaseArray<Derived> e = new BaseArray<Derived>(3);
        // Derived 타입의 BaseArray 객체를 생성합니다.
        e.CopyyArray<Derived>(d.Array); // 각 배열에 값을 할당하고,
                                        // CopyyArray() 메서드를 사용하여 배열을 복사합니다.
    }
}

}

0개의 댓글