본문 바로가기
ZAION/C++

[이것이 C#이다]Ch.06 메소드로 코드 간추리기 - 2

by 우기37 2024. 2. 5.

## 목차

7) 메소드 오버로딩

8) 가변 개수의 인수

9) 명명된 인수

10) 선택적 인수

11) 로컬 함수

 

 

 

 

#7 메소드 오버로딩

메소드 오버로딩은 하나의 메소드 이름에 여러 개의 구현을 올리는 것을 뜻합니다.

 

int Plus(int a, int b)
{
	return a + b;
}

double Plus(double a, double b)
{
	return a + b;
}

 

이렇게 오버로딩을 해놓으면 컴파일러가 메소드 호출 코드에 사용되는 매개변수의 수와 형식을 분석해서(오로지 매개변수만 분석합니다. 반환 형식은 묻지도 따지지도 않습니다.) 어떤 버전이 호출 될지를 찾아줍니다. 실행할 메소드의 버전을 찾는 작업이 컴파일 타임에 이루어지므로 성능 저하는 걱정하지 않아도 됩니다.

 

사용 이유 : 

  1. 메소드 이름에 대한 고민을 줄여줍니다.
  2. 코드를 일관성 있게 유지해줍니다.
  3. 메소드 사용자에세 높은 생산성을 제공합니다.

[실습]

using System;

namespace ThisIsCSharpExam.Ch._06.MethodExam
{
    class OverloadingExam
    {
        public void Main()
        {
            Console.WriteLine(Plus(1, 2));
            Console.WriteLine(Plus(1, 2, 3));
            Console.WriteLine(Plus(1.0, 2.4));
            Console.WriteLine(Plus(1, 2.4));
        }
        static int Plus(int a, int b)
        {
            Console.WriteLine("Calling int Plus(int int)...");
            return a + b;
        }
        static int Plus(int a, int b, int c)
        {
            Console.WriteLine("Calling int Plus(int,int,int....)");
            return a + b + c;
        }
        static double Plus(double a, double b)
        {
            Console.WriteLine("Calling double Plus(double, double...)");
            return a + b;
        }
        static double Plus(int a, double b)
        {
            Console.WriteLine("Calling double Plus(int, double...)");
            return a + b;
        }
    }
}

 

 

 

 

#8 가변 개수의 인수

프로그래밍 하다 보면 그저 인수의 '개수'가 다르다는 이유만으로 똑같은 메소드를 여러 버전으로 오버로딩하고 싶을 때가 있습니다. 이런 경우를 위해 C#은 '가변 개수의 인수'라는 기능을 제공합니다.

 

가변 개수의 인수란 그 개수가 유연하게 변할 수 있는 인수를 말합니다.

 

[실습]

using System;

namespace ThisIsCSharpExam.Ch._06.MethodExam
{
    class UsingParams
    {
        public void Main()
        {
            int sum = Sum(3, 4, 5, 6, 7, 8, 9, 10);
            Console.WriteLine($"Sum : {sum}");
        }
        static int Sum(params int[] args)
        {
            Console.Write("Summing...");
            int sum = 0;
            for (int i = 0; i < args.Length; i++)
            {
                if (i > 0)
                    Console.Write(", ");
                Console.Write(args[i]);
                sum += args[i];
            }
            Console.WriteLine();

            return sum;
        }
    }
}

 

 

 

 

#9 명명된 인수

말 그대로 메소드를 호출할 때 인수의 이름에 근거해서 데이터를 할당할 수 있는 기능입니다.

 

명명된 인수를 사용하기 위해 메소드 선언에 손댈 일은 전혀 없습니다. 메소드를 호출할 때만 인수의 이름 뒤에 콜론(:)을 붙인 뒤 그 뒤에 할당할 데이터를 넣어주면 됩니다.

 

사용 이유 : 

  1. 명명된 인수를 이용해서 코드를 작성해놓으면 코드가 훨씬 읽기 좋아집니다.
  2. 인수가 너무 많아 어느 매개변수에 어느 인수를 할당하고 있는지 분간이 어려운 경우에는 명명된 인수가 도움이 될 것입니다.

[실습]

using System;

namespace ThisIsCSharpExam.Ch._06.MethodExam
{
    class NamedParameter
    {
        public void Main()
        {
            PrintProfile(name: "박찬호", phone: "010-123-1234");
            PrintProfile(phone: "010-123-1234", name: "박지성");
            PrintProfile("박세리", "010-123-1234");
            PrintProfile("손흥민", phone: "010-567-5678");
        }
        static void PrintProfile(string name, string phone)
        {
            Console.WriteLine($"Name:{name}, Phone:{phone}");
        }
    }
}

 

 

 

 

#10 선택적 인수

메소드의 매개변수는 기본값을 가질 수 있습니다. 그러니까 다음과 같이 매개변수를 특정 값으로 초기화하듯 메소드를 선언할 수 있다는 것입니다.

 

void MyMethod(int a, int b = 0)
{
	Console.WriteLine("{0}, {1}", a, b);
}

 

이와 같이 기본값을 가진 매개변수는 메소드를 호출할 때 해당 인수를 생략할 수 있습니다.

MyMethod(3);

 

물론 필요한 경우에는 인수를 입력할 수도 있습니다. 기본값을 가진 매개변수는 필요에 따라 인수를 할당하거나 할당하지 않을 수 있기 때문에 이를 '선택적 인수'라고 부릅니다.

 

또한, 선택적 인수는 항상 필수 인수 뒤에 와야 합니다.

 

선택적 인수는 메소드의 사용자에게 신경 쓰고 싶지 않은 인수를 염두에 두지 않도록 편의를제공하지만, 또 한편으로는 모호함이라는 스트레스도 같이 줍니다.(코드를 작성할 때는 인텔리센스의 도움을 받아 내가 어느 매개변수에 인수를 할당하는지 파악할 수 있지만, 작성한 지 한참이 지난 코드를 다시 들여다보면 내가 어는 매개변수에 어떤 인수를 할당했는지 잘 분간되지 않을 때도 있습니다.)

 

[실습]

using System;

namespace ThisIsCSharpExam.Ch._06.MethodExam
{
    class OptionalParameter
    {
        public void Main()
        {
            PrintProfile("중근");
            PrintProfile("관순", "010-1234-1234");
            PrintProfile(name: "봉길");
            PrintProfile(name: "동주", phone: "010-5678-5678");
        }
        static void PrintProfile(string name, string phone = "")
        {
            Console.WriteLine($"Name:{name}, Phone:{phone}");
        }
    }
}

 

 

 

 

#11 로컬 함수

로컬 함수는 메소드안에서 선언되고, 선언된 메소드 안에서만 사용되는 특별한 함수입니다.

클래스의 멤버사 아니기 때문에 메소드가 아니라 함수라고 부릅니다.

 

선언 방법은 메소드와 다르지 않지만, 로컬 함수는 자신이 존재하는 지역에 선언되어 있는 변수를 사용할 수 있습니다.

 

 [실습]

using System;

namespace ThisIsCSharpExam.Ch._06.MethodExam
{
    class LocalFunction
    {
        public void Main()
        {
            Console.WriteLine(ToLowerString("Hello!"));
            Console.WriteLine(ToLowerString("Good Morning~"));
            Console.WriteLine(ToLowerString("This is C#"));
        }
        static string ToLowerString(string input)   // 메소드 선언
        {
            var arr = input.ToCharArray();
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = ToLowerChar(i);
            }
            char ToLowerChar(int i) // 로컬 함수 선언
            {
                // ToLowerString() 메소드의 지역변수 arr을 사용합니다.
                // 로컬 함수는 자신이 속한 메소드의 지역 변수를 자유롭게 읽고, 쓰기 가능
                if (arr[i] < 65 || arr[i] > 90) // A ~ Z의 ASCII 값 : 65 ~ 90
                    return arr[i];
                else // a ~ z의 ASCII 값 : 97 ~ 122
                    return (char)(arr[i] + 32);
            }
            return new string(arr);
        }
    }
}