반응형
델리게이트란?
메소드를 참조하는 타입으로, 메소드를 변수처럼 저장하고 전달할 수 있게 해주는 기능
특징
- 메소드를 참조할 수 있는 타입
- 타입 안정성 보장
- 체인(다중 델리게이트)이 가능
- 메소드 시그니처가 일치해야 함
사용하는 이유
- 콜백 메커니즘 구현
- 이벤트 처리
- 메소드를 매개변수로 전달
- 유연한 코드 설계
활용 사례
- 이벤트 시스템
- 비동기 프로그래밍
- 플러그인 아키텍처
예시 코드
public class PlayerSystem : MonoBehaviour
{
// 델리게이트 정의
public delegate void PlayerStatusChanged(int health, int mana);
public event PlayerStatusChanged OnStatusChanged;
private int health = 100;
private int mana = 100;
public void TakeDamage(int damage)
{
health -= damage;
// 델리게이트 호출
OnStatusChanged?.Invoke(health, mana);
}
// 델리게이트 활용 예시
private void Start()
{
// UI 업데이트 메소드 등록
OnStatusChanged += UpdateUI;
// 사운드 재생 메소드 등록
OnStatusChanged += PlaySound;
}
private void UpdateUI(int health, int mana)
{
Debug.Log($"UI Updated - Health: {health}, Mana: {mana}");
}
private void PlaySound(int health, int mana)
{
Debug.Log("Playing damage sound effect");
}
}
익명 메서드란?
이름이 없는 메서드를 즉석에서 선언하고 사용할 수 있는 기능
delegate 키워드를 사용하여 정의함
사용 방법
// 익명 메서드의 기본 형태
delegate(매개변수) {
// 메서드 본문
}
// 예시
delegate void MyDelegate(string message);
MyDelegate myDelegate = delegate(string message) {
Debug.Log(message);
};
예시
OriginMethod
delegate int delegateCalc(int a, int b);
int plus(int a, int b)
{
return a + b;
}
void Start()
{
delegateCalc cal = plus;
cal(2, 4);
}
↓ ↓ ↓ ↓ ↓
AnonyMousMethod
delegate int delegateCalc(int a, int b);
void Start()
{
delegateCalc cal = delegate (int i, int j)
{
return i + j;
};
Debug.Log(cal(9,2));
}
특징
- 이름이 불필요 ( 일회성으로 사용되는 메서드를 간단히 정의 )
- 다른 메서드를 넣어주지 않고 델리게이트의 선언과 정의를 동시에 수행
- 외부 변수 접근 가능 ( 클로저 )
private void CreateCounter()
{
int count = 0;
Button button = GetComponent<Button>();
button.onClick.AddListener(delegate() {
count++; // 외부 변수 count에 접근 가능
Debug.Log($"Count: {count}");
});
}
- 델리게이트와 함께 사용
public class GameManager : MonoBehaviour
{
public delegate void ScoreChanged(int newScore);
public event ScoreChanged OnScoreChanged;
private int score = 0;
private void Start()
{
// 익명 메서드로 이벤트 핸들러 등록
OnScoreChanged += delegate(int newScore) {
Debug.Log($"Score changed to: {newScore}");
UpdateUI(newScore);
};
}
private void UpdateUI(int score)
{
// UI 업데이트 로직
}
}
사용하는 이유
- 일회성 메서드를 간단히 구현
- 코드의 간결성 향상
- 지역 변수에 쉽게 접근 가능
- 이벤트 핸들러를 즉석에서 정의
활용 사례와 예시 코드
이벤트 핸들링
public class UIManager : MonoBehaviour
{
public Button startButton;
public Button quitButton;
private void SetupButtons()
{
// 시작 버튼 이벤트
startButton.onClick.AddListener(delegate() {
PlayerPrefs.SetInt("GameStarted", 1);
SceneManager.LoadScene("GameScene");
});
// 종료 버튼 이벤트
quitButton.onClick.AddListener(delegate() {
SaveGameData();
Application.Quit();
});
}
private void SaveGameData()
{
// 게임 데이터 저장 로직
}
}
일회성 이벤트 처리나 콜백 함수에서 매우 유용하게 사용된다
람다식 (Lambda Expression) 이란?
익명 메소드를 간단히 작성할 수 있게 해주는 표현식
사용 방법
=> (람다 연산자)를 사용하여 작성
예시
방법 1
// 기본적인 람다식
MyDelegate delegate2 = (message) => Debug.Log(message);
// 여러 줄의 람다식
MyDelegate delegate3 = (message) => {
string upperMessage = message.ToUpper();
Debug.Log(upperMessage);
};
// Action과 람다식
Action<string> action = (message) => Debug.Log(message);
// Func과 람다식 (반환값이 있는 경우)
Func<int, int> square = x => x * x;
방법 2
익명 메서드
void Start()
{
delegateCalc cal = delegate (int i, int j)
{
return i + j;
};
}
↓ ↓ ↓ ↓ ↓
람다식 방법 1 ( 매개변수 타입 생략 )
void Start()
{
delegateCalc cal = (i, j) =>
{
return i + j;
};
}
람다식 방법 2 (중괄호,return 키워드 추가 생략)
delegate int delegateCalc(int a, int b);
void Start()
{
delegateCalc cal = (i, j) => i + j;
Debug.Log(cal(9,2));
}
특징
- 익명 메소드를 간단히 표현
- => 연산자 사용
- 컴파일러가 타입 추론
- 클로저(외부 변수 캡처) 지원
사용하는 이유
- 코드 간소화
- 일회성 메소드 구현
- LINQ 쿼리 작성
- 즉시 실행 가능한 코드 블록 생성
활용 사례
- LINQ 쿼리
- 이벤트 핸들러
- 컬렉션 조작
- UI 이벤트 처리
예시 코드
public class ItemSystem : MonoBehaviour
{
private List<Item> inventory = new List<Item>();
public class Item
{
public string Name { get; set; }
public int Level { get; set; }
public float Price { get; set; }
}
private void ProcessItems()
{
// 람다식을 사용한 아이템 필터링
var highLevelItems = inventory.Where(item => item.Level > 50);
// 람다식을 사용한 아이템 정렬
var sortedItems = inventory.OrderBy(item => item.Price);
// 람다식을 사용한 아이템 변형
var itemNames = inventory.Select(item => item.Name);
// UI 버튼에 람다식 활용
Button sellButton = GetComponent<Button>();
sellButton.onClick.AddListener(() => {
var selectedItem = inventory.FirstOrDefault(item => item.Level > 0);
if (selectedItem != null)
{
SellItem(selectedItem);
}
});
}
private void SellItem(Item item)
{
Debug.Log($"Selling {item.Name} for {item.Price} gold");
}
}
람다식과 익명메서드의 비교
익명 메서드
Button button = GetComponent<Button>();
button.onClick.AddListener(delegate() {
Debug.Log("Button clicked!");
});
람다식
Button button = GetComponent<Button>();
button.onClick.AddListener(() => {
Debug.Log("Button clicked!");
});
델리게이트와 람다식의 기능을 상황에 맞게 적절히 조합하여 사용하면
더 효율적이고 유지보수가 쉬운 코드를 작성할 수 있다.
또한, 람다식이 더 간결한 문법을 제공하기에 익명메서드 보단
람다식이 보다 선호하는 경향이 있다
그래도 익명 메서드의 개념을 이해해야 델리게이트와 람다식의
동작 원리를 이해하는 데 도움이 되니 모두 이해하는 편이 좋겠다
반응형
'유니티 > 문법' 카테고리의 다른 글
[Unity] 유니티 C#) 전처리문 (Preprocessor Directives) (0) | 2025.01.13 |
---|---|
[Unity] 유니티 C#) Event ( 이벤트 ), Action ( 액션 ) (0) | 2025.01.08 |
[Unity] 유니티 C#) Garbage Collector ( 가비지 컬렉터 ) (0) | 2025.01.06 |
[Unity] 유니티 C#) ObjectPool ( 오브젝트풀링 ) (2) | 2025.01.03 |
[Unity] 유니티 C#) ScriptableObject ( 스크립터블오브젝트 ) (1) | 2025.01.02 |