[C# – 기초 강좌] 4. Csharp 함수(Function)/ 메서드(Method) 이해하기

이번 포스팅에서는 C#의 함수(Function) 및 메서드(Method)의 정의와 사용법에 대해 알아보겠습니다.

특히 이를 사용할 때 같이 사용되는 개념들과 사용법에 대해 알아보고 C#의 최신 문법에는 어떻게 사용하는 경향들이 있는지도 알아보도록 하겠습니다.

함수(Function) vs 메서드(Method)

개요

기본적으로 함수(Function)와 메서드(Method)는 코드의 재사용성을 높이고 프로그램의 구조를 체계적으로 관리할 수 있다는 공통점이 있습니다.

허나, 함수(Function)와 메서드(Method)는 매우 유사해 보이지만, 그 사용범위와 정의하는 컨텍스트에서 미묘한 차이가 있습니다.

이 두 용어는 종종 서로 바꿔 사용되지만, 프로그래밍 언어와 패러다임에 따라 의미하는 바가 조금씩 다를 수 있습니다.

함수 (Function)

함수는 일반적으로 다음과 같은 특징을 가집니다:

  • 독립적인 역할:
    • 함수는 프로그램 내에서 독립적으로 존재할 수 있습니다.
    • 즉, 객체나 클래스에 속하지 않고도 정의하고 호출할 수 있습니다.
  • 입력과 출력:
    • 함수는 일반적으로 입력(인자)를 받아 처리하고 결과(반환값)를 출력합니다.
  • 재사용성:
    • 함수는 코드의 재사용을 증진시키는 주요 도구로, 특정 작업을 수행하는 코드 블록을 반복적으로 사용할 수 있도록 합니다.

메서드 (Method)

메서드는 함수와 유사한 특징을 가지지만, 주로 객체 지향 프로그래밍에서 사용되는 용어로, 다음과 같은 특성을 가집니다:

  • 클래스 또는 객체에 속함:
    • 메서드는 특정 클래스 또는 객체의 일부로 정의됩니다.
    • 메서드는 클래스의 인스턴스 데이터(속성)에 접근하고 조작하는 데 사용됩니다.
  • 캡슐화와 상호작용:
    • 메서드는 객체의 캡슐화된 데이터를 조작하는 주된 수단으로, 객체 내부의 상태를 변경하거나 객체 간의 상호작용을 담당합니다.
  • 상속과 다형성:
    • 객체 지향 언어에서 메서드는 상속을 통해 확장되거나 재정의될 수 있으며, 다형성의 주요 요소로 작용합니다.

간단히 말하면, 함수는 독립적으로 존재 가능한 기능의 단위 이고, 메소드는 클래스에 포함되어 있는 함수를 메소드 라고 부릅니다.

허나 현업에서 이를 명확하게 구분하여 부르지는 않습니다.

C#(Csharp)에서 메서드(Method) 기초

메서드(Method) 기본 구조

C#에서 메서드를 정의하는 기본 구조는 다음과 같습니다.

[접근제어자] [반환형] 메서드이름([매개변수])
{
    // 메서드 본문
}
  • 접근 제어자(Access Modifier):
  • 반환형(Return Type):
    • 메서드가 수행 후 반환하는 데이터의 타입입니다. (반환값이 없을 경우 void를 사용합니다.)
  • 메서드 이름(Method Name):
    • 메서드를 호출할 때 사용하는 이름입니다.
  • 매개변수(Parameters):
    • 외부에서 메서드로 전달되는 값을 받기 위한 변수들입니다.
    • 필요에 따라 매개변수가 없을 수도 있습니다.

정의 및 호출

아래 예제에서 Calculator 클래스 내에 Add() 메서드를 정의했습니다.

Add() 메서드는 두 개의 정수 매개변수(ab)를 받아 그 합을 반환합니다.

메인 프로그램에서는 Calculator 클래스의 인스턴스를 생성하고, Add() 메서드를 호출하여 그 결과를 출력합니다

    public class Calculator
    {
        // Define Add() method with two parameters
        public int Add(int a, int b)
        {
            return a + b;
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Calculator calc = new Calculator();
            // call Add() method
            int result = calc.Add(5, 3);
            Console.WriteLine("5 + 3 = " + result);
        }
    }

매개변수(Parameters)와 반환값(Return Value)

매개변수 (Parameters)

매개변수는 메서드에 전달되는 입력 값입니다.

메서드를 정의할 때, 매개변수를 통해 메서드가 처리할 데이터의 유형과 개수를 지정할 수 있습니다.

매개변수는 메서드 내부에서 변수처럼 사용되며, 메서드 호출 시 지정된 값으로 초기화됩니다.

위 예제에서는 Add()메서드의 int a, int b가 매개변수에 해당합니다.

매개변수는 다음과 같이 기본 값(Default Value)를 지정하여 해당 매개변수의 값의 입력을 생략할 수도 있습니다.

    public class Calculator
    {
        // Define Add() method with two parameters (b has a default value 10)
        public int Add(int a, int b = 10)
        {
            return a + b;
        }
    }

반환값 (Return Value)

반환값은 메서드가 수행한 계산이나 작업의 결과를 호출한 곳으로 보내는 값입니다.

메서드를 정의할 때 반환 타입을 지정해야 하며, 반환 타입이 void가 아닌 경우 메서드 내에서 반드시 return 문을 사용해 해당 타입의 값을 반환해야 합니다.

Add() 메서드에서는 integer 타입을 반환하도록 정의하였습니다.

오버로딩(Overloading)과 재귀 함수(Recursive Function)

개요

오버로딩(Overloading) 은 같은 이름의 메서드를 매개변수의 유형이나 개수가 다르게 하여 여러 버전을 만드는 기법입니다.

재귀 함수(Recursion) 는 메서드가 자기 자신을 호출하는 방식으로 작동합니다.

오버로딩(Overloading)

메서드 오버로딩은 같은 이름의 메서드를 다른 매개변수 세트로 여러 번 정의하는 것을 말합니다.

이를 통해 같은 연산에 대해 다양한 입력 유형이나 매개변수의 수를 처리할 수 있습니다.

예제

다음과 같이 매개변수와 반환형으로 int 형과 double 형을 다르게 받는 두 함수 Multiply()를 정의합니다.

    public class Calculator
    {
        // Overloading: Multiply() method with different parameters
        public int Multiply(int x, int y)
        {
            Console.WriteLine("Multiply(int x, int y)");
            return x * y;
        }
        public double Multiply(double x, double y)
        {
            Console.WriteLine("Multiply(double x, double y)");
            return x * y;
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            // call Multiply() method (overloading)
            int result1 = calc.Multiply(5, 3);
            Console.WriteLine("5 * 3 = " + result1);

            double result2 = calc.Multiply(5.5, 3.5);
            Console.WriteLine("5.5 * 3.5 = " + result2);
        }
    }

다음과 같이 int 타입을 매개변수로 넣었을 때와 double 타입을 매개변수로 넣었을 때,

다른 함수가 호출되었음을 알 수 있습니다.

Multiply(int x, int y)
5 * 3 = 15
Multiply(double x, double y)
5.5 * 3.5 = 19.25

재귀 함수

재귀 함수는 자기 자신을 호출하는 함수로, 복잡한 문제를 간단하게 분해하여 해결할 수 있습니다.

대표적인 예로 팩토리얼 계산이 있습니다.

예제

다음 예제에서 Factorial() 메서드는 종료 조건을 만날 때까지 반복적으로 재귀함수인 Factorial()를 호출합니다.

    public class Calculator
    {
        // recursive method example
        public int Factorial(int n)
        {
            if (n <= 1) return 1; // finish condition
            return n * Factorial(n - 1); // call recursive method again
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            // call Factorial() method
            int n = 5;
            int resultFactorial = calc.Factorial(n);
            Console.WriteLine("Factorial of " + n + " is " + resultFactorial);
        }
    }

익명 메서드 (Anonymous method)

이름이 없는 메서드로, 주로 대리자(delegate)를 사용하여 이벤트 핸들러나 다른 메서드 호출에서 코드를 인라인으로 삽입할 때 사용됩니다.

익명 메서드는 람다 표현식이 도입되기 전에 자주 사용되었고, 여전히 레거시 코드에서 볼 수 있습니다

Func<int, int, int> add = delegate (int x, int y) { return x + y; }; // Define an anonymous method
Console.WriteLine(add(3, 4)); // Use the anonymous method

C#에서의 최신 함수 및 메서드 사용법

1. 로컬 함수 (Local Functions)

로컬 함수는 메서드 내부에 선언되는 함수로, 외부에서는 접근할 수 없어 캡슐화를 강화할 수 있습니다.

예제

int AddLocal(int x, int y) => x + y; // Define a local function
Console.WriteLine(AddLocal(3, 4)); // Call the local function

2. 람다 표현식(Lambda Expressions)

익명 함수를 생성하는 간결한 방법으로, 주로 LINQ 쿼리, 이벤트 처리, FuncAction과 같은 대리자(delegate) 사용에 활용됩니다.

람다 표현식을 이해하고 사용하는 것은 코드를 더 간결하고 가독성 있게 만드는 데 큰 도움이 됩니다.

람다 표현식의 기본 구조는 다음과 같습니다.

(입력 매개변수) => 표현식 또는 { 문장; }

예제

Func<int, int, int> multiply = (x, y) => x * y; // Define a lambda expression
Console.WriteLine(multiply(5, 2)); // Use the lambda expression

3. 표현식 본문 정의(Expression-bodied member)

표현식 본문 정의(Expression-bodied member)는 C# 6.0에서 도입된 문법으로, 클래스 멤버들을 더욱 간결하게 표현할 수 있게 해주는 기능입니다.

이 문법은 주로 간단한 메서드나 속성에 대한 정의를 한 줄의 코드로 축약할 수 있게 해줍니다.

이는 코드의 가독성을 향상시키고, 메서드와 속성의 선언을 더욱 간결하게 만들어줍니다.

예제

    public class Person
    {
        private string name;
        // Constructor with Expression-bodied member
        public Person(string name) => this.name = name; // Constructor

        // Property with Expression-bodied member
        public string Name
        {
            get => name; // Property
            set => name = value;
        }

        public void Print() => Console.WriteLine(name); // Method with Expression-bodied member
    }

4. 비동기 메서드 (Async Method)

비동기 메서드(async 메서드)는 비동기 프로그래밍을 위해 특별히 설계된 기능으로, asyncawait 키워드를 사용하여 구현됩니다.

이러한 메서드들은 주로 I/O 작업, 긴 연산, 웹 서비스 호출 등과 같이 시간이 많이 소요되는 작업을 처리할 때 사용되며, 이를 통해 UI 응답성을 유지하거나 서버의 스레드 사용을 최적화할 수 있습니다.

반환 타입으로 Task<T> 또는 void 타입으로 반환합니다.

예제

async 키워드를 넣어 비동기 함수를 정의하고, 비동기 함수를 await 을 사용하여 호출하고 작업완료를 기다리게 됩니다.

await 키워드는 비동기 함수 내에서만 사용할 수 있습니다.

    public class Program
    {
        public static async Task<string> DownloadDataAsync(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();
                    return content;
                }
                else
                {
                    throw new Exception("Failed to download data.");
                }
            }
        }

        public static async Task Main(string[] args)
        {
            try
            {
                string url = "https://www.google.com";
                string resDownload = await DownloadDataAsync(url);
                Console.WriteLine("Downloaded data:");
                Console.WriteLine(resDownload);
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred: " + ex.Message);
            }
        }
    }

참고 링크

Leave a Comment

Discover more from Devitworld

Subscribe now to keep reading and get access to the full archive.

Continue reading