24.01.18 TIL - [C#] 기초 (13) : 델리게이트, 람다 및 LINQ | Nullable, 문자열 빌더

JJwoo·2024년 1월 17일
0

C#

목록 보기
17/20

🕋 델리게이트(Delegate)

  • 델리게이트 요약
    • 델리게이트(delegate)는 메서드를 참조하는 타입입니다.
    • 다른 프로그래밍 언어에서는 함수 포인터라는 용어를 사용하기도 합니다.
    • 델리게이트를 이용하면 메서드를 매개변수로 전달하거나 변수에 할당할 수 있습니다.

C#과 같은 프로그래밍 언어에서 매우 중요한 개념이며 다음과 같은 특징을 가진다.

  1. 함수 포인터: 델리게이트는 기본적으로 함수에 대한 참조, 즉 함수 포인터와 비슷합니다. 이를 통해 함수를 다른 함수나 메서드의 인자로 전달하거나, 변수에 할당할 수 있습니다.

  2. 타입 안전성: 델리게이트는 타입 안전한 방법으로 함수를 다룹니다. 즉, 델리게이트는 특정 시그니처(반환 타입과 매개변수)를 가진 함수만 참조할 수 있습니다.

  3. 이벤트 처리: 델리게이트는 이벤트 기반 프로그래밍에서 중요한 역할을 합니다. 이벤트가 발생했을 때 호출되어야 하는 메서드를 지정하는 데 사용됩니다.

  4. 익명 메서드와 람다 표현식과의 결합: 델리게이트는 익명 메서드나 람다 표현식과 결합하여 사용될 수 있어, 코드를 간결하고 유연하게 작성할 수 있도록 도와줍니다.

유니티 게임 개발에서의 예를 들면, 플레이어의 행동(예: 점프, 공격 등)에 대한 반응으로 특정 함수를 호출하고 싶을 때 델리게이트를 사용할 수 있습니다. 이를 통해, 플레이어의 행동에 따라 다양한 효과나 게임 로직을 유연하게 연결할 수 있습니다.

public delegate void MyDelegate(string message); // 델리게이트 정의

public class DelegateExample
{
    public void ShowMessage(string message)
    {
        Console.WriteLine(message);
    }

    public void Execute()
    {
        MyDelegate del = ShowMessage; // 델리게이트 인스턴스화
        del("Hello, World!"); // 델리게이트를 통해 메서드 호출
    }
}

이 코드에서 MyDelegate는 문자열을 매개변수로 받는 메서드를 참조할 수 있는 델리게이트 타입입니다. Execute 메서드에서 ShowMessage 메서드를 MyDelegate 타입의 del 변수에 할당하고, 이를 통해 메서드를 호출합니다.

예제2)

2) 델리게이트 구현
메서드 등록해서 사용하기

delegate int Calculate(int x, int y);

static int Add(int x, int y)
{
    return x + y;
}

class Program
{
    static void Main()
    {
        // 메서드 등록
        Calculate calc = Add;

        // 델리게이트 사용
        int result = calc(3, 5);
        Console.WriteLine("결과: " + result);
    }
}
  • 3) 예제 하나 이상의 메서드 등록하기
delegate void MyDelegate(string message);

static void Method1(string message)
{
    Console.WriteLine("Method1: " + message);
}

static void Method2(string message)
{
    Console.WriteLine("Method2: " + message);
}

class Program
{
    static void Main()
    {
        // 델리게이트 인스턴스 생성 및 메서드 등록
        MyDelegate myDelegate = Method1;
        myDelegate += Method2;

        // 델리게이트 호출
        myDelegate("Hello!");

        Console.ReadKey();
    }
}

  • 4) 예제
    • 공격 콜백 받기
      • 다음 예제에서는 event 를 붙여서 사용했다
      • event는 할당연산자( = )를 사용할 수 없으며, 클래스 외부에서는 직접 이벤트를 호출할 수 없다.

// 델리게이트 선언
public delegate void EnemyAttackHandler(float damage);

// 적 클래스
public class Enemy
{
    // 공격 이벤트
    public event EnemyAttackHandler OnAttack;

    // 적의 공격 메서드
    public void Attack(float damage)
    {
        // 이벤트 호출
        OnAttack?.Invoke(damage);
				// null 조건부 연산자
				// null 참조가 아닌 경우에만 멤버에 접근하거나 메서드를 호출
    }
}

// 플레이어 클래스
public class Player
{
    // 플레이어가 받은 데미지 처리 메서드
    public void HandleDamage(float damage)
    {
        // 플레이어의 체력 감소 등의 처리 로직
        Console.WriteLine("플레이어가 {0}의 데미지를 입었습니다.", damage);
    }
}

// 게임 실행
static void Main()
{
    // 적 객체 생성
    Enemy enemy = new Enemy();

    // 플레이어 객체 생성
    Player player = new Player();

    // 플레이어의 데미지 처리 메서드를 적의 공격 이벤트에 추가
    enemy.OnAttack += player.HandleDamage;

    // 적의 공격
    enemy.Attack(10.0f);
}

이 코드는 C#의 델리게이트와 이벤트를 활용하여 게임 내에서 적(Enemy)이 플레이어(Player)에게 공격을 가하는 상황을 모델링하고 있습니다.

  • 델리게이트 선언 (EnemyAttackHandler)
    이는 float 타입의 매개변수를 받는 메서드를 참조할 수 있는 델리게이트 타입을 정의합니다.
    이 델리게이트는 적의 공격이 발생했을 때 호출될 메서드의 시그니처를 정의합니다.
  • 적 클래스 (Enemy)
    Enemy 클래스 내에 EnemyAttackHandler 델리게이트 타입을 사용하는 OnAttack 이벤트가 선언되어 있습니다.
    Attack 메서드는 적이 공격하는 로직을 구현하며, 공격 시 OnAttack 이벤트를 트리거합니다.
    OnAttack?.Invoke(damage); 구문은 OnAttack 이벤트에 등록된 메서드가 있을 경우에만 호출하도록 합니다. 이는 null 조건부 연산자를 사용한 안전한 이벤트 호출 방법입니다.
    플레이어 클래스 (Player)

  • HandleDamage 메서드는 플레이어가 데미지를 받았을 때의 처리를 담당합니다.
    이 메서드는 EnemyAttackHandler 델리게이트의 시그니처와 일치하므로, OnAttack 이벤트에 연결될 수 있습니다.

  • 게임 실행 로직
    Main 메서드에서는 Enemy와 Player 객체를 생성하고, Player의 HandleDamage 메서드를 Enemy의 OnAttack 이벤트에 등록합니다.
    적의 Attack 메서드를 호출하면, 이벤트가 트리거되고 Player의 HandleDamage 메서드가 실행됩니다.
    이벤트 특징:

  • event 키워드는 델리게이트를 캡슐화하여 외부에서의 직접적인 접근을 제한합니다.
    클래스 외부에서는 이벤트에 메서드를 추가(+=)하거나 제거(-=)할 수 있지만, 직접 호출하거나 할당(=)할 수는 없습니다. 이는 이벤트의 발생을 클래스 내부 로직에만 한정시켜, 외부에서의 무분별한 이벤트 발생을 방지합니다.


λ 람다

람다 요약

  • 람다(lambda)는 익명 메서드를 만드는 방법입니다.
  • 람다를 사용하면 메서드의 이름 없이 메서드를 만들 수 있습니다.
  • 람다는 델리게이트를 사용하여 변수에 할당하거나, 메서드의 매개변수로 전달할 수 있습니다.

람다(lambda) 표현식은 C#에서 매우 유용한 기능으로, 익명 메서드(이름이 없는 메서드)를 생성하는 간결한 방법을 제공합니다. 람다 표현식은 특히 LINQ 쿼리, 이벤트 처리, 델리게이트 할당 등에 널리 사용됩니다.

  • 기본 구조: 람다 표현식은 다음과 같은 형식을 가집니다
    여기서 => 연산자는 "goes to" 또는 "람다 연산자"라고 불립니다.
(input-parameters) => expression
// 인자 없는 람다 표현식
() => Console.WriteLine("Hello World");

// 한 개의 인자를 받는 람다 표현식
x => x * x;

// 여러 개의 인자를 받는 람다 표현식
(x, y) => x + y;

람다 구현

1) 형식

(parameter_list) => expression

2) 정의하기

Calculate calc = (x, y) => 
{	
		return x + y;
};

Calculate calc = (x, y) => x + y;

3) 사용예제

using System;

// 델리게이트 선언
delegate void MyDelegate(string message);

class Program
{
    static void Main()
    {
        // 델리게이트 인스턴스 생성 및 람다식 할당
        MyDelegate myDelegate = (message) =>
        {
            Console.WriteLine("람다식을 통해 전달된 메시지: " + message);
        };

        // 델리게이트 호출
        myDelegate("안녕하세요!");

        Console.ReadKey();
    }
}
  • 게임의 분기 시작을 알리기
// 델리게이트 선언
public delegate void GameEvent();

// 이벤트 매니저 클래스
public class EventManager
{
    // 게임 시작 이벤트
    public event GameEvent OnGameStart;

    // 게임 종료 이벤트
    public event GameEvent OnGameEnd;

    // 게임 실행
    public void RunGame()
    {
        // 게임 시작 이벤트 호출
        OnGameStart?.Invoke();

        // 게임 실행 로직

        // 게임 종료 이벤트 호출
        OnGameEnd?.Invoke();
    }
}

// 게임 메시지 클래스
public class GameMessage
{
    public void ShowMessage(string message)
    {
        Console.WriteLine(message);
    }
}

// 게임 실행
static void Main()
{
    // 이벤트 매니저 객체 생성
    EventManager eventManager = new EventManager();

    // 게임 메시지 객체 생성
    GameMessage gameMessage = new GameMessage();

    // 게임 시작 이벤트에 람다 식으로 메시지 출력 동작 등록
    eventManager.OnGameStart += () => gameMessage.ShowMessage("게임이 시작됩니다.");

    // 게임 종료 이벤트에 람다 식으로 메시지 출력 동작 등록
    eventManager.OnGameEnd += () => gameMessage.ShowMessage("게임이 종료됩니다.");

    // 게임 실행
    eventManager.RunGame();
}


유니티 게임 개발에서의 활용

  • 람다 표현식은 유니티에서 이벤트 리스너나 콜백 함수를 작성할 때 매우 유용합니다.
  • 예를 들어, 버튼 클릭 이벤트에 람다 표현식을 사용하여 코드를 간결하게 만들 수 있습니다.
  • 또한, 코루틴에서 비동기 작업의 완료 후 처리를 위해 사용될 수 있습니다.

예시 코드)

using System;
using System.Collections.Generic;
using UnityEngine;

public class LambdaExample : MonoBehaviour
{
    void Start()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        // List에서 홀수만 필터링
        List<int> oddNumbers = numbers.FindAll(n => n % 2 != 0);
        
        // 홀수 출력
        oddNumbers.ForEach(n => Debug.Log(n));
    }
}

이 예제에서 FindAll 메서드는 람다 표현식을 사용하여 홀수를 필터링합니다. 람다 표현식 n => n % 2 != 0은 각 요소 n이 홀수인지를 평가합니다. ForEach 메서드는 또 다른 람다 표현식을 사용하여 필터링된 홀수를 출력합니다.

람다 표현식은 코드를 간결하고 읽기 쉽게 만들어 줄 뿐만 아니라, 함수형 프로그래밍 스타일을 C#에 통합하는 데 중요한 역할을 합니다. 유니티 개발에서도 람다를 활용하면 이벤트 처리, 데이터 처리 등 다양한 곳에서 코드를 더욱 효율적으로 작성할 수 있습니다.



🚲 Func과 Action

Func과 Action은 델리게이트를 대체하는 미리 정의된 제네릭 형식입니다.
(델리게이트 대신 더 많이 쓰는 편)

  • FuncAction델리게이트를 대체하는 미리 정의된 제네릭 형식입니다.

  • Func는 값을 반환하는 메서드를 나타내는 델리게이트입니다. 마지막 제네릭 형식 매개변수는 반환 타입을 나타냅니다. 예를 들어, Func<int, string>int를 입력으로 받아 string을 반환하는 메서드를 나타냅니다.

  • Action은 값을 반환하지 않는 메서드를 나타내는 델리게이트입니다. Action은 매개변수를 받아들이지만, 반환 타입이 없습니다. 예를 들어, Action<int, string>intstring을 입력으로 받고, 아무런 값을 반환하지 않는 메서드를 나타냅니다.

  • FuncAction은 제네릭 형식으로 미리 정의되어 있어 매개변수와 반환 타입을 간결하게 표현할 수 있습니다.

2) 사용 예제

Func 예제



// Func를 사용하여 두 개의 정수를 더하는 메서드
int Add(int x, int y)
{
    return x + y;
}

// Func를 이용한 메서드 호출
Func<int, int, int> addFunc = Add;
int result = addFunc(3, 5);
Console.WriteLine("결과: " + result);

Action 예제
// Action을 사용하여 문자열을 출력하는 메서드
void PrintMessage(string message)
{
    Console.WriteLine(message);
}

// Action을 이용한 메서드 호출
Action<string> printAction = PrintMessage;
printAction("Hello, World!");

활용 예제

아래 예제는 게임 개발에서 캐릭터 상태 변경에 대한 반응을 구현하는 방법을 보여줍니다.

Action과 람다 표현식을 사용하면, 이벤트나 상태 변경에 대한 로직을 유연하고 간결하게 작성할 수 있습니다.

// 게임 캐릭터 클래스
class GameCharacter
{
    private Action<float> healthChangedCallback;

    private float health;

    public float Health
    {
        get { return health; }
        set
        {
            health = value;
            healthChangedCallback?.Invoke(health);
        }
    }

    public void SetHealthChangedCallback(Action<float> callback)
    {
        healthChangedCallback = callback;
    }
}

// 게임 캐릭터 생성 및 상태 변경 감지
GameCharacter character = new GameCharacter();
character.SetHealthChangedCallback(health =>
{
    if (health <= 0)
    {
        Console.WriteLine("캐릭터 사망!");
    }
});

// 캐릭터의 체력 변경
character.Health = 0;

여기서 Action 델리게이트는 매개변수로 float 값을 받고 반환 값이 없는 메서드를 참조합니다. 이 코드는 게임 캐릭터의 체력이 변경될 때마다 특정한 동작을 실행하는 메커니즘을 구현하고 있습니다.

GameCharacter 클래스

  • healthChangedCallback은 Action 타입의 델리게이트로, 체력이 변경될 때 호출될 메서드를 참조합니다.
  • Health 프로퍼티는 게임 캐릭터의 체력을 나타냅니다. 체력 값이 설정될 때마다 healthChangedCallback을 호출하여 체력 변경을 알립니다.

  • SetHealthChangedCallback 메서드
    이 메서드는 외부에서 healthChangedCallback을 설정할 수 있도록 합니다. 이를 통해 체력이 변경될 때 실행될 콜백 함수를 지정할 수 있습니다.
    캐릭터 생성 및 콜백 설정

  • GameCharacter 인스턴스를 생성하고, SetHealthChangedCallback 메서드를 통해 체력 변경 시 호출될 콜백 함수를 람다 표현식을 사용하여 정의합니다.
    이 람다 표현식은 캐릭터의 체력이 0 이하로 떨어질 때 "캐릭터 사망!"을 출력합니다.

  • 캐릭터 체력 변경
    character.Health = 0; 구문은 캐릭터의 체력을 0으로 설정합니다. 이에 따라 콜백 함수가 호출되고, 캐릭터의 사망 메시지가 출력됩니다.



📑 LINQ (Language Integrated Query)

  • 1) LINQ란?
    • .NET 프레임워크에서 제공되는 쿼리 언어 확장
    • 데이터 소스(예: 컬렉션, 데이터베이스, XML 문서 등)에서 데이터를 쿼리하고 조작하는데 사용됩니다.
    • 데이터베이스 쿼리와 유사한 방식으로 데이터를 필터링, 정렬, 그룹화, 조인 등 다양한 작업을 수행할 수 있습니다.
    • LINQ는 객체, 데이터베이스, XML 문서 등 다양한 데이터 소스를 지원합니다.

LINQ(Language Integrated Query)는 C# 및 .NET 프레임워크에서 데이터를 쿼리하는 강력한 기능입니다.

LINQ는 데이터 소스에 관계없이 일관된 쿼리 언어를 제공합니다.

데이터 소스가 컬렉션, SQL 데이터베이스, XML 문서, 데이터 세트 등 무엇이든 간에, LINQ를 사용하여 데이터를 쉽고 간결하게 조회하고 조작할 수 있습니다.

LINQ의 주요 특징:

  • 통합된 쿼리 언어: LINQ는 SQL과 유사한 쿼리 구문을 C# 코드 내에서 직접 사용할 수 있게 해줍니다.

  • 다양한 데이터 소스 처리: LINQ는 다양한 유형의 데이터 소스에 적용될 수 있습니다. 예를 들어, LINQ to Objects는 메모리 내 컬렉션에, LINQ to SQL은 SQL 데이터베이스에, LINQ to XML은 XML 문서에 적용됩니다.

  • 객체 지향적 접근: LINQ 쿼리의 결과는 객체의 컬렉션으로 반환됩니다. 이를 통해, 쿼리 결과를 객체와 같은 방식으로 쉽게 다룰 수 있습니다.

  • 컴파일 시간 검증: LINQ 쿼리는 컴파일 시간에 타입 검사가 이루어지므로, 런타임 오류를 줄일 수 있습니다.

  • 읽기 쉽고 유지보수하기 쉬운 코드: LINQ는 쿼리를 명확하고 선언적인 방식으로 작성할 수 있게 해, 코드의 가독성과 유지보수성을 향상시킵니다.

  • 2) 구조

    var result = from 변수 in 데이터소스
                 [where 조건식]
                 [orderby 정렬식 [, 정렬식...]]
                 [select];
    
    • var 키워드는 결과 값의 자료형을 자동으로 추론합니다.
    • from 절에서는 데이터 소스를 지정합니다.
    • where 절은 선택적으로 사용하며, 조건식을 지정하여 데이터를 필터링합니다.
    • orderby 절은 선택적으로 사용하며, 정렬 방식을 지정합니다.
    • select 절은 선택적으로 사용하며, 조회할 데이터를 지정합니다.

예제1)

// 데이터 소스 정의 (컬렉션)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// 쿼리 작성 (선언적인 구문)
var evenNumbers = from num in numbers
                where num % 2 == 0
                select num;

// 쿼리 실행 및 결과 처리
foreach (var num in evenNumbers)
{
  Console.WriteLine(num);
}  

C#의 LINQ(Language Integrated Query) 기능을 활용하여 컬렉션 내의 짝수를 찾는 간단한 예제

LINQ의 선언적 쿼리 구문을 사용하여 numbers 리스트에서 짝수만을 선택하고 출력합니다.

데이터 소스 정의

List numbers = new List { 1, 2, 3, 4, 5 };
여기서 numbers는 int 타입의 리스트로, LINQ 쿼리의 대상이 되는 데이터 소스입니다.

  • from num in numbers: numbers 컬렉션의 각 요소를 num이라는 변수로 순회합니다.

  • where num % 2 == 0: num % 2 == 0 조건을 만족하는 요소, 즉 짝수를 필터링합니다.

  • select num: 필터링된 요소를 선택하여 새로운 컬렉션을 만듭니다.

  • 이 쿼리는 numbers 리스트에서 짝수만을 선택하는 LINQ 쿼리입니다.

쿼리 실행 및 결과 처리

  • LINQ 쿼리의 결과인 evenNumbers를 foreach 루프를 통해 순회하면서 각 요소를 출력합니다.

  • 이 부분에서 쿼리가 실제로 실행됩니다. LINQ 쿼리는 대개 "지연 실행"(deferred execution) 방식을 따릅니다.

  • 즉, 쿼리 자체는 선언 시에 실행되지 않고, 실제로 결과가 필요한 시점(이 경우 foreach 루프)에 실행됩니다.


예제2)

using System;
using System.Linq;
using System.Collections.Generic;

class LinqExample
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

        // LINQ를 사용하여 짝수만 필터링
        var evenNumbers = from num in numbers
                          where num % 2 == 0
                          select num;

        foreach (var n in evenNumbers)
        {
            Console.WriteLine(n);
        }
    }
}

이 예제에서는 LINQ를 사용하여 리스트 numbers에서 짝수만을 선택(select)하고 있습니다. from 절은 컬렉션을 반복하고, where 절은 조건을 기반으로 필터링을 수행합니다. 결과적으로, 이 코드는 리스트에서 짝수만 추출하여 출력합니다.

유니티 게임 개발에서도 LINQ는 데이터 처리, 특히 복잡한 컬렉션 조작이 필요할 때 유용하게 사용됩니다. 예를 들어, 특정 조건을 만족하는 게임 오브젝트를 찾거나, 데이터를 정렬하고 그룹화하는 데에 LINQ 쿼리를 활용할 수 있습니다.


01. Nullable 형

  • 1) null

    • null은 "아무것도 없음"을 의미한다.

    • 참조형 변수가 어떠한 객체를 참조하지 않을 때 사용됩니다.

    • 예시: string str = null; 여기서 str은 어떤 문자열도 참조하지 않습니다.

  • 2) Nullable 란?

    • Nullable은 C#에서 null 값을 가질 수 있는 값형에 대한 특별한 형식입니다.

    • 기본적으로 값형은 null을 허용하지 않습니다.

    • 값형 변수에 null 값을 지정할 수 있는 방법을 제공하여 값형이나 구조체를 사용하는 프로그램에서 null 상태를 나타낼 수 있습니다. 주로 값형 변수가 null인지 아닌지를 확인하고 처리해야 할 때 유용합니다.

    • 형식은 ? 연산자를 사용하여 선언됩니다. 예를 들어, int?는 int 형식에 null을 할당할 수 있는 Nullable 형식을 나타냅니다.

  • 예시: int? num = null; 여기서 num은 int 값형에 null을 할당할 수 있습니다.

3) 사용 예제

  
// Nullable 형식 변수 선언
int? nullableInt = null;
double? nullableDouble = 3.14;
bool? nullableBool = true;

// 값 할당 및 접근
nullableInt = 10;
int intValue = nullableInt.Value;

// null 값 검사
if (nullableDouble.HasValue)
{
    Console.WriteLine("nullableDouble 값: " + nullableDouble.Value);
}
else
{
    Console.WriteLine("nullableDouble은 null입니다.");
}

// null 병합 연산자 사용
// nullableInt ?? 0과 같이 사용되며, nullableInt가 null이면 0을 반환합니다.
int nonNullableInt = nullableInt ?? 0;
Console.WriteLine("nonNullableInt 값: " + nonNullableInt);
  

Nullable의 중요성

  • 값형에 대한 유연성: Nullable은 값형 변수에 null 할당을 가능하게 하여, 값이 '없음' 또는 '알 수 없음'을 표현할 수 있도록 해줍니다.
  • 데이터베이스와의 호환성: 데이터베이스에서는 null 값을 자주 사용합니다. Nullable을 통해 데이터베이스의 null 값을 값형 변수에 할당하거나, 반대로 처리할 수 있습니다.
    옵셔널 데이터 처리: 값의 존재 여부가 불분명한 경우에 Nullable을 사용하여, 값이 설정되지 않은 상태를 표현할 수 있습니다.

유니티에서의 적용 예시

유니티 게임 개발에서 Nullable은 특정 컴포넌트나 값이 아직 할당되지 않았거나 더 이상 유효하지 않은 경우를 표현하는 데 유용합니다.

예를 들어, 플레이어의 점수나 캐릭터의 체력이 초기화되지 않았을 때 null로 표현할 수 있습니다. 이를 통해 게임 로직에서 유효하지 않은 상태를 쉽게 처리하고 오류를 방지할 수 있습니다.

  public class Player : MonoBehaviour
{
    // Nullable을 사용하여 초기 점수를 null로 설정
    int? score = null;

    void Start()
    {
        // 점수가 설정되지 않았다면 특정 로직 실행
        if (score == null)
        {
            Debug.Log("점수가 아직 설정되지 않았습니다.");
        }
    }
}

이 코드에서 score 변수는 Nullable int로 선언되어, 초기에는 null 값을 가집니다. 이를 통해 게임이 시작될 때 플레이어의 점수가 아직 설정되지 않았음을 표현하고, 이에 따른 특정 로직을 실행할 수 있습니다.


문자열 빌더 (StringBuilder)

StringBuilder는 C#에서 문자열을 조작할 때 사용되는 클래스입니다. 특히 문자열을 반복적으로 수정할 때 StringBuilder를 사용하면, 일반 문자열(string) 조작에 비해 성능상의 이점이 있습니다.

  • 1) StringBuilder 란?
    1. 문자열 조작
      StringBuilder는 Append(), Insert(), Replace(), Remove() 등 다양한 메서드를 제공하여 문자열에 대한 추가, 삽입, 치환, 삭제 작업을 수행할 수 있습니다.
    2. 가변성
      StringBuilder는 내부 버퍼를 사용하여 문자열 조작을 수행하므로 크기를 동적으로 조정할 수 있습니다. 따라서 문자열의 크기가 늘어나거나 줄어들어도 추가적인 메모리 할당이 발생하지 않습니다.
    3. 효율적인 메모리 관리
      문자열 조작 시 StringBuilder는 내부 버퍼를 사용하여 문자열을 조작하므로, 반복적인 문자열 조작 작업이 발생해도 메모리 할당 및 해제 오버헤드가 크게 감소합니다.


  • 2) 주요 메서드
    • Append: 문자열을 뒤에 추가합니다.
    • Insert: 문자열을 지정한 위치에 삽입합니다.
    • Remove: 지정한 위치에서 문자열을 제거합니다.
    • Replace: 문자열의 일부를 다른 문자열로 대체합니다.
    • Clear: StringBuilder의 내용을 모두 지웁니다.
  StringBuilder sb = new StringBuilder();

// 문자열 추가
sb.Append("Hello");
sb.Append(" ");
sb.Append("World");

// 문자열 삽입
sb.Insert(5, ", ");

// 문자열 치환
sb.Replace("World", "C#");

// 문자열 삭제
sb.Remove(5, 2);

// 완성된 문자열 출력
string result = sb.ToString();
Console.WriteLine(result);

유니티에서의 적용:

유니티 게임 개발에서 StringBuilder는 주로 게임 내 텍스트 정보를 동적으로 생성하거나 수정할 때 사용됩니다. 예를 들어, 점수판, 인벤토리 설명, 게임 로그 등의 텍스트를 구성할 때 StringBuilder를 활용하면 성능상 이점을 얻을 수 있습니다.

using UnityEngine;
using System.Text;

public class GameStatus : MonoBehaviour
{
    void UpdateScore(int score, int lives)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("Score: ").Append(score).Append(" - Lives: ").Append(lives);

        // 여기서 UpdateScore 메서드는 점수판 UI 텍스트를 업데이트할 수 있습니다.
        UpdateScoreText(sb.ToString());
    }

    void UpdateScoreText(string text)
    {
        // 점수판 UI 업데이트 로직
        Debug.Log(text);
    }
}

이 예제에서는 점수와 생명 수를 표시하는 문자열을 StringBuilder를 사용하여 구성하고 있습니다. StringBuilder를 사용함으로써 문자열 연결이나 수정 시 발생할 수 있는 성능 저하를 최소화할 수 있습니다.

profile
개발 모코코

0개의 댓글