C# - ๊ณ ๊ธ‰ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ œ๋„ค๋ฆญ)

2020. 11. 27. 16:25ใ†์ „๊ณต ๊ณผ๋ชฉ/์œˆ๋„์šฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

C# - ๊ณ ๊ธ‰ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ œ๋„ค๋ฆญ)

 

์ œ๋„ค๋ฆญ

  • ๋ณ€์ˆ˜์˜ ํ˜•์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ•˜์—ฌ ํด๋ž˜์Šค๋‚˜ ๋ฉ”์†Œ๋“œ์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ธฐ์ˆ ํ•˜๋Š” ๊ธฐ๋ฒ•.
  • ์‹ค์ œ ํ˜• ์ •๋ณด๋Š” "๊ฐ์ฒด ์ƒ์„ฑ ์‹œ"์— ์ „๋‹ฌ๋ฐ›์Œ

์ œ๋„ค๋ฆญ๋Š” ํด๋ž˜์Šค์ด๋ฉด์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋‹ค์–‘์„ฑ์„ ๋‹ด๋Š” ์œ ๋™์ ์ธ ํด๋ž˜์Šค๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

 

์ฆ‰ intํ˜•์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด์˜ค๋ฉด intํ˜•์— ๋”ฐ๋ผ ๋ฐฐ์—ด์„ ๋งŒ๋“ ๋‹ค๊ฑฐ๋‚˜, ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , doubleํƒ€์ž…์˜ ํ˜•์ด ๋“ค์–ด์˜ค๋ฉด doubleํƒ€์ž…์— ๋งž์ถฐ์„œ ํด๋ž˜์Šค ๋‚ด๋ถ€๊ฐ€ ์ง„ํ–‰์ด ๋œ๋‹ค.  

 

์ œ๋„ค๋ฆญ ํด๋ž˜์Šค ์‚ฌ์šฉ์˜ ์˜ˆ

 class SimpleGeneric<T> {
        private T[] values;
        private int index;
        public SimpleGeneric(int len)
        {
            values = new T[len];
            index = 0;
        }
        public void Add(params T[] args)
        {
            foreach (T e in args)
                values[index++] = e;
        }
        public void Print()
        {
            foreach (T e in values)
                Console.Write(e + " ");
            Console.WriteLine();
        }
    }  
    public class GenericClassExample {
        static void Main(string[] args)
        {
            SimpleGeneric<Int32> gInteger = new SimpleGeneric<Int32>(10);
            SimpleGeneric<Double> gDouble = new SimpleGeneric<double>(10);

            gInteger.Add(1, 2);
            gInteger.Add(1, 2, 3, 4, 5, 6, 7);
            gInteger.Add(0);
            gInteger.Print();

            gDouble.Add(10.1, 20.2, 30.3);
            gDouble.Print();
        }
    }

 

๊ฒฐ๊ณผ ํ™”๋ฉด

์œ„์— Add๋ฐฐ์—ด์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ params๋ฅผ ์ ๋Š” ์ด์œ ๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ’๋“ค์ด ์ง์ ‘์ ์œผ๋กœ ๋“ค์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

์ œ๋„ค๋ฆญ ์ธํ„ฐํŽ˜์ด์Šค

์ œ๋„ค๋ฆญ๋„ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์กด์žฌํ•˜๋ฉฐ ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 interface IGenericInterface<T>
    {
        void SetValue(T x);
        string GetValueType();

    }
    class GenericClass<T> : IGenericInterface<T>
    {
        private T value;
        public void SetValue(T x)
        {
            value = x;
        }
        public String GetValueType()
        {
            return value.GetType().ToString();
        }
        public class GenericInterfaceApp
        {
            static void Main(string[] args)
            {
                GenericClass<Int32> gInteger = new GenericClass<Int32>();
                GenericClass<String> gString = new GenericClass<string>();

                gInteger.SetValue(10);
                gString.SetValue("Text");

                Console.WriteLine(gInteger.GetValueType());
                Console.WriteLine(gString.GetValueType());
            }
        }
    }

์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์™ธ๋ถ€๋งŒ ๊ตฌํ˜„ํ•œ ๋’ค ์‚ฌ์šฉํ•  ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค์— ์ƒ์†์‹œ์ผœ ์žฌ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. GetType๋ฉ”์†Œ๋“œ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๋ฉ”์†Œ๋“œ์ด๋‹ค.

 

์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ

- ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ๋Š” ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋‹ค์–‘์„ฑ์„ ์œ„ํ•ด์„œ ๊ณ ์•ˆ๋œ ๋ฉ”์†Œ๋“œ์ด๋‹ค. ์œ ์˜ํ•  ์ ์€ ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค์˜ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„๊ณผ ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ์˜ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์ด ๊ฐ™์„ ๋•Œ, ์„œ๋กœ ๋…๋ฆฝ๋œ ๊ฐœ๋…์„ ๊ฐ€์ง€๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฆ‰ ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค๋Š” ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ์— ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌ๋ฐ›๊ณ , ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ๋Š” ํ˜ธ์ถœ ์‹œ์— ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๊ฒฐ์ •์ด ๋œ๋‹ค. 

 

 

์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ ์˜ˆ์ œ

class GenericMethodApp
    {
        static void Swap<DataType>(ref DataType x, ref DataType y)
        {
            DataType temp;
            temp = x; x = y; y = temp;
        }
    
        
            static void Main(string[] args)
            {
            int a = 1, b = 2; double c = 1.5, d = 2.5;
            Console.WriteLine("Before: a ={0}, b = {1}", a, b);
            Swap<int>(ref a, ref b);
            Console.WriteLine("After : a= {0}, b = {1}", a, b);
            Console.WriteLine("Before: c ={0}, d = {1}", c, d);
            Swap<double>(ref c, ref d);
            Console.WriteLine("After : c ={0}, b = {1}", c, d);

        }
    }

๋งค๊ฐœ๋ณ€์ˆ˜์— ref๋ฅผ ์ ๋Š” ์ด์œ ๋Š” ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์ ‘๊ทผํ•ด์•ผ ์‹ค์ œ ๋ณ€์ˆ˜๋“ค์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ Call by value(๊ฐ’), Call by reference(์ฐธ์กฐ)๋ฅผ ๊ฒ€์ƒ‰ํ•ด๋ณด์ž.

 

์ œ๋„ค๋ฆญ์€ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹ ๋ขฐ์„ฑ์„ ์ฆ์ง„์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ „๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ž๋ฃŒํ˜•์˜ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

์ด๋ฅผ ํ•œ์ •์‹œํ‚ค๊ธฐ ์œ„ํ•ด where ๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

where T : S๋ผ๋Š” ๊ฒŒ ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค ์ •์˜ ๋’ค์— ๋ถ™๋Š”๋‹ค๋ฉดSํ˜•์˜ ์„œ๋ธŒํด๋ž˜์Šคํ˜•์œผ๋กœ ์ œํ•œํ•œ๋‹ค์˜ ๋œป์ด ๋œ๋‹ค.

 

์†Œ์Šค๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด์ž.

class GenericType<T> where T : SystemException
    {
        private T value;
        GenericType(T v) { value = v; }
        public override string ToString()
        {
            return "Type is" + value.GetType();
        }
    }
    public class BoundedGenericApp
    {
        public static void Main(string[] args)
        {
            GenericType<NullReferenceException> gNullEx =
                new GenericType<NullReferenceException>(new NullReferenceException());
            GenericType<IndexOutOfRangeException> gIndexEx =
                new GenericType<IndexOutOfRangeException>(new IndexOutOfRangeException());

            Console.WriteLine(gNullEx.ToString());
            Console.WriteLine(gIndexEx.ToString());
        }
    }

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ ๋‘๊ฐ€์ง€์ด๋‹ค.

1) where๋ฅผ ํ†ตํ•ด์„œ T์˜ ๋ฒ”์œ„๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. (์˜ˆ์™ธ๋งŒ ์ƒ์†๋ฐ›์•˜๊ธฐ์— String์ด๋‚˜ intํ˜•์ด ์˜ฌ ์ˆ˜ ์—†๋‹ค.)

2) ์˜ˆ์™ธ ๋˜ํ•œ ๊ฐ์ฒด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.