C# · 심층 가이드
C# 함수 완전 정리
메서드 선언과 기본값, 가변 인자에서 시작해 람다와 클로저, 메모이제이션, 커링, 파이프라인까지 C#에서 함수를 값으로 다루는 스무 가지 방법을 모았습니다.
C#에서 함수라는 말은 최소 네 가지를 가리킵니다. 타입에 속한 메서드, 메서드 안에 선언하는 로컬 함수, 델리게이트 인스턴스, 그리고 람다 식입니다. 겉보기에는 다 같은 호출이지만 Func나 Action 같은 델리게이트로 넘기는 순간 값이 되어 변수에 담기고 다른 함수의 인자가 됩니다. 함수를 일급 값으로 쓰는 코드가 낯설다면, 이 전환 지점을 먼저 눈에 익히는 편이 빠릅니다. 이름 있는 메서드와 이름 없는 람다가 결국 같은 델리게이트 타입에 들어간다는 것만 확인해도 뒷부분이 훨씬 수월해집니다.
기본 함수 선언과 두 값을 더하는 함수로 형태를 잡은 뒤 람다 함수로 넘어가면 같은 로직이 값으로 바뀝니다. 그 상태에서 고차 함수 map과 정렬용 비교 함수를 보면 함수를 인자로 받는 쪽이 어떻게 생겼는지 잡힙니다. 클로저 카운터부터는 함수가 바깥 변수를 붙잡는 이야기로 넘어가고, 메모이제이션과 함수 팩토리는 그 캡처를 캐시와 설정 주입에 각각 활용한 사례입니다. 마지막의 파이프라인 함수는 앞의 compose 함수를 여러 단계로 늘린 형태라 두 예제를 이어서 보면 좋습니다.
기본값 매개변수는 편해 보이지만 값이 호출하는 쪽 코드에 박혀 컴파일된다는 성질이 있습니다. 라이브러리에서 기본값만 바꾸고 다시 배포해도, 호출하는 어셈블리를 다시 컴파일하지 않으면 예전 값이 그대로 쓰입니다. 공개 API라면 기본값 대신 오버로드가 안전합니다. 클로저 카운터 쪽에서는 람다가 값이 아니라 변수 자체를 캡처한다는 점을 기억해야 하고, 특히 for 루프 변수는 반복마다 새로 만들어지지 않아 모든 람다가 같은 변수를 공유합니다.
01기본 함수 선언
C#에서 기본 함수 선언 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 기본 함수 선언
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(1, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
02두 값을 더하는 함수
C#에서 두 값을 더하는 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 두 값을 더하는 함수
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
03기본값 매개변수
C#에서 기본값 매개변수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 기본값 매개변수
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(3, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
04가변 인자 합계
C#에서 가변 인자 합계 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 가변 인자 합계
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
05객체 또는 구조체 반환
C#에서 객체 또는 구조체 반환 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 객체 또는 구조체 반환
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(5, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
06람다 함수
C#에서 람다 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 람다 함수
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
07클로저 카운터
C#에서 클로저 카운터 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 클로저 카운터
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(7, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
08재귀 팩토리얼
C#에서 재귀 팩토리얼 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 재귀 팩토리얼
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
09고차 함수 map
C#에서 고차 함수 map 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 고차 함수 map
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(9, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
10조건 함수 predicate
C#에서 조건 함수 predicate 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 조건 함수 predicate
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
11정렬용 비교 함수
C#에서 정렬용 비교 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 정렬용 비교 함수
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(11, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
12문자열 파서
C#에서 문자열 파서 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 문자열 파서
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
13함수 팩토리
C#에서 함수 팩토리 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 함수 팩토리
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(13, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
14메모이제이션
C#에서 메모이제이션 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 메모이제이션
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
15커링
C#에서 커링 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 커링
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(15, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
16compose 함수
C#에서 compose 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// compose 함수
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
17제네릭 함수
C#에서 제네릭 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 제네릭 함수
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(17, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
18콜백으로 완료 알림
C#에서 콜백으로 완료 알림 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 콜백으로 완료 알림
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
19reducer 함수
C#에서 reducer 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// reducer 함수
using System;
int Add(int a, int b) => a + b;
Console.WriteLine(Add(19, 2));매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
20파이프라인 함수
C#에서 파이프라인 함수 개념을 코드로 빠르게 확인하는 함수 예제입니다.
C# code
// 파이프라인 함수
using System;
Func<int> CreateCounter() { var current = 0; return () => ++current; }
var next = CreateCounter();
Console.WriteLine(next());매개변수와 반환값을 함께 읽으면 함수의 책임이 더 선명하게 보입니다.
함수 선언과 호출을 따로 읽으면 매개변수 순서나 반환값을 놓치기 쉽습니다.
정리하며
- 람다를
Func나Action에 담는 순간 함수가 전달 가능한 값이 됩니다 - 공개 API의 기본값 매개변수는 호출부에 박히므로 오버로드로 두는 편이 안전합니다
- 클로저는 값이 아니라 변수를 캡처하며
for루프 변수는 반복 간에 공유됩니다 - 메모이제이션은 캡처한 딕셔너리 하나로 만들 수 있지만 키 설계와 수명은 따로 챙깁니다
더 깊이 들어가고 싶다면 C# 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.