C# 함수/클래스 일반화(Generic 제네릭)

728x90
  • 일반화(Generic)

- 클래스, 함수 일반화 가능

- <T> 키워드

- Boxing, UnBoxing을 줄일 수 있음

- 불필요한 오버로딩을 줄일 수 있음

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

namespace _103_GenericFunc
{
    class Program
    {
        static void GenericPrint<T>(T data)
        {
            Console.WriteLine("data : {0}", data);
        }
        static void GenericPrint<T>(T[] arrData)
        {
            for(int i = 0; i < arrData.Length; i++)
            {
                Console.WriteLine("arrData : {0}", arrData[i]);
            }
        }
        static void Main(string[] args)
        {
            int a = 10;
            float b = 10.3f;
            string c = "Hello";

            int[] arrA = { 0, 1, 2, 3 };
            string[] arrB = { "A", "B", "C", "D" };

            GenericPrint(a);
            GenericPrint(b);
            GenericPrint(c);

            Console.WriteLine();
            GenericPrint(arrA);
            Console.WriteLine();
            GenericPrint(arrB);
        }
    }
}

 

- 클래스 일반화

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

namespace _104_GenericClass
{
    class GenericAA<T>
    {
        private T num;

        public T GetNum()
        {
            return num;
        }
        public void SetNum(T data)
        {
            num = data;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            GenericAA<int> AA = new GenericAA<int>();
            AA.SetNum(100);
            Console.WriteLine("AA : " + AA.GetNum());

            GenericAA<float> BB = new GenericAA<float>();
            BB.SetNum(100.30f);
            Console.WriteLine("BB : " + BB.GetNum());
        }
    }
}

 

  • dynamic 키워드

- object, var

- 런타임에 변수 형식 변경 가능

- 일반화 함수에 변수타입 대응가능

 

  • default 키워드

- value type : 0 초기화

- reference type : null 초기화

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

namespace _105_dynamic
{
    class Program
    {
        static T AddArray<T>(T[] arrDatas)
        {
            //T temp = 0; //에러 발생
            //object temp = 0; //박싱, 언박싱 발생
            dynamic temp = default(T); //null이 아니다
            for (int i = 0; i < arrDatas.Length; i++)
            {
                temp += arrDatas[i];
            }
            return temp;
        }
        static T SumArray<T>(T[] arrDatas)
        {
            T temp = default(T);
            for (int i = 0; i < arrDatas.Length; i++)
            {
                temp += (dynamic)arrDatas[i];
            }
            return temp;
        }
        static void PrintArray<T>(T[] arrDatas)
        {
            foreach (var data in arrDatas)
            {
                Console.WriteLine("data : {0}", data);
            }
        }
        static void Main(string[] args)
        {
            int[] arrNums = { 1, 2, 3, 4, 5 };

            Console.WriteLine("AddArray : {0}", AddArray(arrNums));
            PrintArray(arrNums);
        }
    }
}

 

  • where 키워드(한정자)

- 매개변수 제한 기능

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

namespace _106_where
{
    class REF
    {

    }
    class AA<T> where T : struct //값형식으로 제한
    {
        private T sData;

        public AA()
        {
            sData = default(T);
        }
        public void Print()
        {
            Console.WriteLine("" + sData);
        }
    }
    class BB<T> where T : class //참조 형식으로 제한
    {
        private T sRefData;
        public BB()
        {
            sRefData = default(T);
        }
        public void Print()
        {
            if (sRefData == null)
                Console.WriteLine("Null sRefData");
            else
                Console.WriteLine("sRefData : " + sRefData);
        }
    }
    interface II
    {
        void IIPrint();
    }
    class CC<T> where T : II //interface로 제한
    {
        public T _interface;
    }
    class DD : II
    {
        public void IIPrint()
        {
            Console.WriteLine("DDbase : ");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //AA<REF> bb = new AA<REF>(); //오류 : null 허용되지 않는 value type
            AA<int> aa = new AA<int>();
            aa.Print();

            //BB<int> bb = new BB<int>(); //오류 : 참조형식이 아니므로
            BB<REF> bb = new BB<REF>();
            bb.Print();

            CC<II> cc = new CC<II>();
            //cc._interface = new REF(); //오류 : 한정자가 interface
            cc._interface = new DD();
            cc._interface.IIPrint();
        }
    }
}

 

https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

 

형식 매개 변수에 대한 제약 조건 - C# 프로그래밍 가이드

형식 매개 변수에 대한 제약 조건을 알아봅니다. 제약 조건은 형식 인수에 포함되어야 하는 기능을 컴파일러에 알립니다.

docs.microsoft.com

 

  • 일반화 컬렉션(Collections Generic)

- 컬렉션의 박싱과 언박싱의 단점을 해결

- List<T>

- Queue<T>

- Stack<T>

- Dictionary<T>

 

728x90