프로그램을 작성하다 보면 동일한 코드를 여러 번 사용하거나, 하나의 기능을 처리하기 위해 많은 코드를 작성하는 경우가 있습니다.
이러한 코드를 하나의 기능으로 묶어 필요할 때마다 호출할 수 있도록 만든 것이 메서드(Method)입니다.
메서드를 활용하면 중복된 코드를 줄일 수 있고, 기능별로 코드를 분리하여 가독성과 유지보수성을 높일 수 있습니다.
메서드란?
메서드는 특정 작업을 수행하기 위해 작성한 코드의 묶음입니다.
예를 들어 게임이 시작되었을 때 메시지를 출력하는 기능을 만든다고 가정해 보겠습니다.
using System;
class Program
{
static void PrintMessage()
{
Console.WriteLine("게임 시작");
}
static void Main()
{
PrintMessage();
PrintMessage();
}
}
실행 결과
게임 시작
게임 시작
PrintMessage()는 게임 시작이라는 메시지를 출력하는 메서드입니다. Main()에서 PrintMessage()를 두 번 호출했기 때문에 같은 메시지가 두 번 출력됩니다.
만약 메서드를 사용하지 않았다면 동일한 Console.WriteLine() 코드를 반복해서 작성해야 했을 것입니다.
지금은 한 줄의 코드에 불과하지만, 여러 줄로 구성된 기능이라면 어떨까요?
동일한 기능을 여러 곳에서 사용해야 할 때 메서드로 분리해 두면 중복을 줄일 수 있고, 수정이 필요할 때도 해당 메서드만 수정하면 됩니다.
메서드의 구조
메서드는 기본적으로 다음과 같은 구조를 가집니다.
static int Add(int a, int b)
{
return a + b;
}
각각의 요소를 살펴보면 다음과 같습니다.
| 구성 요소 | 설명 |
| static | 정적 메서드임을 나타내는 한정자 |
| int | 메서드가 반환하는 값의 자료형 |
| Add | 메서드 이름 |
| (int a, int b) | 메서드가 전달받는 매개변수 |
| { } | 메서드에서 실행할 코드 |
| return | 메서드 실행을 종료하고 결과를 반환 |
여기서 static은 객체를 생성하지 않고 클래스 이름 등을 통해 호출할 수 있는 정적 메서드임을 나타냅니다.
이번 글에서는 메서드의 기본적인 동작을 이해하기 위해 static 메서드를 사용하겠습니다.
매개변수와 인수
메서드는 단순히 정해진 작업을 수행하는 것뿐 아니라, 외부에서 전달받은 값을 이용하여 작업을 수행할 수도 있습니다.
이때 사용하는 것이 매개변수(Parameter)와 인수(Argument)입니다.
두 용어는 비슷해 보이지만 의미에는 차이가 있습니다.
- 매개변수(Parameter) : 메서드를 선언할 때 전달받을 값을 저장하도록 정의한 변수
- 인수(Argument) : 메서드를 호출할 때 실제로 전달하는 값이나 표현식
예제를 살펴보겠습니다.
static void PrintDamage(int damage)
{
Console.WriteLine($"피해량 : {damage}");
}
static void Main()
{
int attack = 30;
PrintDamage(attack);
PrintDamage(50);
}
실행 결과
피해량 : 30
피해량 : 50
여기서 PrintDamage(int damage)의 damage는 매개변수입니다.
반면 PrintDamage(attack)의 attack과 PrintDamage(50)의 50은 메서드를 호출할 때 전달하는 인수입니다.
즉, 호출하는 쪽에서 인수를 전달하면 메서드는 매개변수를 통해 해당 값을 사용하게 됩니다.
값에 의한 전달
C#에서는 별도의 키워드를 사용하지 않으면 기본적으로 값을 복사하여 매개변수에 전달합니다.
static void ChangeNumber(int number)
{
number = 100;
}
static void Main()
{
int value = 10;
ChangeNumber(value);
Console.WriteLine(value);
}
실행 결과
10
ChangeNumber() 내부에서 number에 100을 할당했지만 원본 변수인 value는 여전히 10입니다.
그 이유는 number가 value의 값을 복사받은 별도의 변수이기 때문입니다.
따라서 메서드 내부에서 number를 수정하더라도 원본 변수인 value에는 영향을 주지 않습니다. 다만 이러한 예제는 int와 같은 값 형식을 기준으로 설명한 것입니다.
클래스와 같은 참조 형식을 전달하는 경우에는 객체 자체가 복사되는 것이 아니라 객체를 가리키는 참조값이 복사됩니다. 따라서 동일한 객체를 참조하고 있다면 메서드 내부에서도 해당 객체의 상태를 변경할 수 있습니다.
또한 ref나 out을 사용하면 값을 복사하는 대신 변수 자체를 참조로 전달할 수도 있습니다.
2026.09.27 - [TIL] - [CS] ref와 out의 차이점
return과 반환값
앞서 작성한 메서드들은 전달받은 값을 이용해 작업을 수행했지만, 그 결과를 호출한 쪽으로 반환하지는 않았습니다.
그렇다면 메서드에서 계산한 결과를 다른 곳에서도 사용하고 싶다면 어떻게 해야 할까요? 이때 사용하는 것이 return입니다.
return은 메서드의 실행을 종료하고, 필요한 경우 결과값을 호출한 쪽으로 반환하는 키워드입니다.
static int Add(int a, int b)
{
return a + b;
}
static void Main()
{
int result = Add(10, 20);
Console.WriteLine(result);
}
실행 결과
30
Add()는 두 정수를 전달받아 더한 결과를 반환하는 메서드입니다.
여기서 주의할 부분은 메서드 앞에 선언한 반환 형식입니다.
static int Add(int a, int b)
반환 형식을 int로 선언했기 때문에 return을 통해 int 형식의 값을 반환해야 합니다.
Add(10, 20)을 호출하면 메서드 내부에서 계산한 결과인 30이 반환되고, 해당 값이 result에 저장됩니다.
void와 return
그렇다면 앞서 작성했던 PrintMessage()처럼 반환 형식이 void인 경우는 어떨까요?
void는 메서드가 반환값을 제공하지 않는다는 의미입니다.
static void PrintMessage()
{
Console.WriteLine("게임 시작");
}
따라서 반환할 값이 없다면 return을 작성하지 않아도 됩니다.
하지만 void 메서드에서도 return을 사용할 수 있습니다.
static void CheckHealth(int hp)
{
if (hp <= 0)
{
Console.WriteLine("캐릭터 사망");
return;
}
Console.WriteLine("캐릭터 생존");
}
이 메서드는 HP가 0 이하라면 캐릭터 사망 메시지를 출력한 다음 return을 통해 실행을 종료합니다.
따라서 그 아래에 작성된 캐릭터 생존 메시지는 실행되지 않습니다.
즉, return은 단순히 값을 반환하는 역할뿐 아니라 메서드의 실행을 즉시 종료하는 역할도 합니다.
메서드를 사용하는 이유
메서드의 구조와 매개변수, 반환값을 살펴보았습니다. 그렇다면 실제로 메서드를 사용하는 이유는 무엇일까요?
가장 큰 이유는 기능을 분리하고 중복된 코드를 줄이기 위해서입니다.
예를 들어 게임에서 공격력과 방어력을 이용해 최종 피해량을 계산한다고 가정해 보겠습니다.
static int CalculateDamage(int attack, int defense)
{
int damage = attack - defense;
if (damage < 0)
damage = 0;
return damage;
}
이 메서드는 공격력에서 방어력을 뺀 결과를 반환하며, 피해량이 음수가 되지 않도록 처리합니다.
메서드로 분리해 두면 필요한 곳에서 동일한 계산 방식을 사용할 수 있습니다.
int damage1 = CalculateDamage(100, 30);
int damage2 = CalculateDamage(80, 50);
Console.WriteLine(damage1); // 70
Console.WriteLine(damage2); // 30
만약 피해량 계산 방식을 변경해야 한다면 CalculateDamage() 내부만 수정하면 됩니다.
반대로 같은 계산식을 여러 곳에 직접 작성했다면 각각의 코드를 찾아 수정해야 할 것입니다.
이처럼 메서드는 코드의 재사용성을 높일 뿐 아니라, 하나의 기능을 한곳에서 관리할 수 있도록 만드는 역할도 합니다.
로컬 함수(Local Function)
일반적으로 메서드는 클래스 내부에 선언하지만, C#에서는 메서드 내부에도 함수를 선언할 수 있습니다.
이를 로컬 함수(Local Function)라고 합니다.
다음 예제를 살펴보겠습니다.
static void Main()
{
int bonus = 10;
int CalculateDamage(int attack)
{
return attack + bonus;
}
int damage = CalculateDamage(50);
Console.WriteLine(damage);
}
실행 결과
60
CalculateDamage()는 Main() 내부에 선언된 로컬 함수입니다.
일반적인 메서드와 달리 Main() 내부에서 선언되었기 때문에 해당 로컬 함수가 선언된 범위 안에서만 사용할 수 있습니다.
또한 로컬 함수는 자신을 감싸고 있는 메서드의 지역 변수에도 접근할 수 있습니다.
위 예제에서는 Main()의 지역 변수인 bonus를 별도의 매개변수로 전달하지 않았지만, 로컬 함수 내부에서 사용할 수 있었습니다.
로컬 함수는 언제 사용할까?
로컬 함수는 특정 메서드 내부에서만 필요한 기능을 분리할 때 사용할 수 있습니다.
예를 들어 하나의 메서드에서만 사용하는 계산이나 검사 기능이 있다면, 이를 로컬 함수로 분리하여 관련 코드를 함께 관리할 수 있습니다.
반대로 여러 메서드에서 공통으로 사용해야 하는 기능이라면 일반적인 메서드로 분리하는 편이 적합합니다.
따라서 로컬 함수는 해당 기능을 사용하는 범위를 제한하고, 관련된 코드를 가까운 곳에서 관리하고 싶을 때 활용할 수 있습니다.
정리
이번 글에서는 C# 메서드의 기본적인 구조와 매개변수, 반환값, 로컬 함수에 대해 살펴보았습니다.
| 개념 | 설명 |
| 메서드(Method) | 특정 기능을 수행하는 코드의 묶음 |
| 매개변수(Parameter) | 메서드에서 전달받을 값을 위해 선언한 변수 |
| 인수(Argument) | 메서드 호출 시 실제로 전달하는 값이나 표현식 |
| return | 메서드 실행을 종료하고 필요한 경우 값을 반환 |
| void | 반환값이 없음을 나타내는 반환 형식 |
| 로컬 함수(Local Function) | 메서드 등의 내부에 선언하여 제한된 범위에서 사용하는 함수 |
메서드를 사용하는 가장 큰 목적은 단순히 코드를 짧게 작성하기 위해서가 아닙니다.
반복되는 기능을 분리하고, 코드의 재사용성과 유지보수성을 높이기 위해서입니다.
또한 매개변수와 반환값을 활용하면 메서드가 어떤 데이터를 전달받고, 어떤 결과를 제공하는지 명확하게 표현할 수 있습니다.
게임 개발에서도 이동, 공격, 피해량 계산, 상태 변경 등 다양한 기능을 메서드로 분리하여 사용합니다.
따라서 메서드의 기본적인 구조와 데이터가 전달되는 과정을 정확히 이해하는 것이 중요하겠습니다.
'TIL' 카테고리의 다른 글
| [CS] ref와 out의 차이점 (0) | 2026.10.10 |
|---|---|
| [CS] Object와 박싱/언박싱 (0) | 2026.09.24 |
| [CS] 값 형식과 참조 형식 (0) | 2026.09.22 |
| [Unity 2D] 무기 시스템 (전략 패턴) (0) | 2026.04.23 |