* 해당 글은 게임 프로그래머 입문 올인원 강의를 보고 정리한 글입니다
https://www.inflearn.com/roadmaps/355#introduce
MMORPG 게임 개발, 켠김에 끝판왕까지! (유니티 + C#) 로드맵 - 인프런
C#, Unity 스킬을 학습할 수 있는 게임 개발 로드맵을 인프런에서 만나보세요.
www.inflearn.com
* 다차원 배열, 가변 배열
// 다차원 배열 ///////////////////////////////////////////////
int[,] tile =
{
{ 1, 1, 1, 1 },
{ 1, 0, 0, 1 },
{ 1, 0, 0, 1 },
{ 1, 0, 0, 1 },
{ 1, 1, 1, 1 },
};
var defaultColor = Console.ForegroundColor;
for (int i = 0; i < tile.GetLength(0); i++)
{
for (int j = 0; j < tile.GetLength(1); j++)
{
if (tile[i, j] == 1)
Console.ForegroundColor = ConsoleColor.Red;
else
Console.ForegroundColor = ConsoleColor.Green;
Console.Write('\u25cf');
}
Console.WriteLine();
}
// 가변 배열 /////////////////////////////////////////////////
Console.ForegroundColor = defaultColor;
int[][] a = new int[3][];
a[0] = new int[3];
a[1] = new int[6];
a[2] = new int[2];
* Dictionary → Hash Table
* 제너릭(Generic)
데이터 형식에 의존하지 않고 재사용 가능한 코드를 작성할 수 있도록 해주는 기능
즉, 다양한 자료형에 대해 형식 안정성 있는 재사용 가능한 코드를 작성할 수 있게 해주는 기능이다
[쉽게 말하면]
"자료형은 나중에 정하자!"라는 개념
[제너릭 타입에도 조건을 넣을 수 있음 - where 제약조건]
1. 참조형만 가능(nullable 포함)
where T : class
2. Monster 타입이거나, Monster를 상속(파생)한 타입만 가능
where T : Monster
3. 값 형식만 가능(int, float, 사용자 정의 구조체 등, nullable 포함)
ㄴ enum도 값 형식이기 때문에 허용되지만,
정확히 열거형만 허용하려면 where T : Enum을 사용하는 것이 더 명확함(C# 7.3부터 지원)
where T : struct
4. 매개변수가 없는 기본 생성자가 반드시 있어야 함
where T : new()
[주의] 항상 가장 마지막에 써야 함
where T : class, new()
5. 제네릭 타입이 2개 이상일 경우, 각각 개별 제약 가능
ㄴ K는 참조형만 가능
ㄴ V는 값 형식만 가능
public class Test<K, V>
where K : class
where V : struct
* 인터페이스(interface)
컨벤션으로 I를 주로 붙여줌
https://shine94.tistory.com/422
[C#] 오버라이딩 정리
* 오버로딩 (Overloading) 같은 이름, 다른 매개변수로 메서드를 여러 개 정의(컴파일 타임 다형성)* 오버라이딩 (Overriding) 부모로부터 상속받은 메서드를 자식 클래스에서 재정의(런타임 다형
shine94.tistory.com
https://shine94.tistory.com/424
[C#] 추상 클래스와 인터페이스의 차이
* 추상 클래스(abstract class) 기본 구현과 상속을 통해 확장할 수 있는 기본 구현, 설계 뼈대를 제공 일반 메서드와 virtual 메서드가 있으며, virtual 메서드만 오버라이드(재정의) 가능 추상(a
shine94.tistory.com
* 프로퍼티(property)
객체 지향 언어에서 필드에 대한 안전한 접근을 제공하는 특수한 메서드
필드 값을 직접 노출하지 않고, get/set 접근자를 통해 제어 → getter, setter라고 부름
접근 제어자(private set, public get 등)도 설정 가능 → 은닉 + 캡슐화
namespace CSharp
{
class Program
{
static void Main(string[] args)
{
Knight k = new Knight();
Console.WriteLine(k.Hp);
}
}
}
class Knight
{
private int _hp;
public int Hp
{
get { return _hp; }
//set { Hp = value; }
private set { _hp = value; }
}
}
class Knight
{
public int Hp { get; set; } = 100;
}
* 대리자(delegate)
함수를 변수처럼 저장하고, 나중에 실행할 수 있게 해주는 C#의 함수 포인터
리턴 타입과 매개변수의 시그니처가 일치하기만 하면, 대리자 변수에 저장 후 호출 가능
[이름이 대리자인 이유?]
단순히 함수 주소를 넘기는 포인터가 아니라, 객체 지향 언어의 철학에 맞게 설계된 "타입이 보장된 함수 참조자"다
그래서 함수 포인터 보다 의미도, 책임도 더 크기 때문에 대리자라는 이름을 쓴다
[객체 지향 언어의 철학?]
함수도 객체처럼 다루고 싶어함
[타입 검사 어떻게?]
함수의 리턴 타입과 매개변수 시그니처를 기준으로 수행함
* 대리자 체이닝(chaining)
대리자는 객체이기 때문에, 여러 개의 함수를 누적 등록하고 순서대로 호출할 수 있다
[누적 호출이란?]
체이닝된 모든 함수가 등록된 순서대로 호출되는 것
[만약, 리턴값이 있는 경우?]
리턴 값이 있는 대리자 체이닝인 경우, 마지막 함수의 반환 값만 사용된다
따라서, 체이닝은 일반적으로 void 반환에서 가장 유용하게 사용 된다
delegate void MyDelegate();
void A() => Console.WriteLine("A 실행");
void B() => Console.WriteLine("B 실행");
void C() => Console.WriteLine("C 실행");
MyDelegate del = A;
del += B;
del += C;
del();
// 출력 : A, B, C
delegate int MyCalc();
int A() { Console.WriteLine("A"); return 1; }
int B() { Console.WriteLine("B"); return 2; }
MyCalc calc = A;
calc += B;
int result = calc();
// 출력: A, B
// result = 2 (마지막 값)
* 이벤트(event)
객체 내부에서 특정 일이 발생했을 때 외부에 통보해주는 구조
ㄴ 대리자 기반 알림(신호) 매커니즘
[동작 방식]
콜백 함수를 등록해놓고, 나중에 호출되는 구조
[예시]
버튼이 클릭 → 등록한 함수 호출
체력이 0됨 → 죽음 이벤트 발생
정리하자면, 대리자를 기반으로 만든, 외부에서 구독만 가능한 함수 호출 도구이다
ㄴ 즉, C#의 event는 옵저버 패턴(Observer Pattern)을 기반으로 설계된 공식 기능이다
외부에서 직접 호출이나 초기화 등 대리자(delegate)의 권한을 제한하여 안전성을 높인다.
namespace CSharp
{
class Program
{
static void OnInputTest()
{
Console.WriteLine("OnInputTest 함수");
}
static void Main(string[] args)
{
InputManager manager = new InputManager();
// 이벤트 구독 (+=)
manager.InputKey += OnInputTest;
// 직접 호출 불가 (event는 외부 호출 막힘)
// manager.InputKey(); ← 컴파일 에러 발생
while (true)
{
manager.Update(); // 키 입력 감지 루프
}
}
}
class InputManager
{
public delegate void OnInputKey(); // 델리게이트 정의
public event OnInputKey InputKey; // 이벤트 정의
public void Update()
{
if (!Console.KeyAvailable)
return;
ConsoleKeyInfo info = Console.ReadKey();
if (info.Key == ConsoleKey.A)
{
// 구독된 메서드 호출 (이벤트 발생)
InputKey?.Invoke(); // 안전하게 null 체크
}
}
}
}
* 대리자는 래핑(wrapping)한 문법적 구조
🔌 delegate = 멀티탭 → 아무 데나 꽂고 조작 가능
🔒 event = 안전 커버 덮인 멀티탭 → 구독(+=)만 허용, 직접 호출은 불가
* 람다식(lambda expression)
익명함수를 간결하게 표현하는 문법
// 익명 함수 (delegate 키워드 사용)
delegate (매개변수) { 식 또는 문장 블록 }
// 람다식으로 표현 (delegate 키워드 생략)
(매개변수) => 식 또는 문장 블록
delegate Return MyFunc<Return>();
delegate Return MyFunc<T, Return>(T val);
delegate Return MyFunc<T1, T2, Return>(T1 val1, T2 val2);
* 예외처리(Exception)
System.Object
└── System.Exception
├── System.SystemException
│ ├── System.NullReferenceException
│ ├── System.IndexOutOfRangeException
│ ├── System.StackOverflowException
│ ├── System.OutOfMemoryException
│ ├── System.DivideByZeroException
│ ├── System.FormatException
│ └── ... (기타 시스템 예외)
└── System.ApplicationException
└── (사용자 정의 예외)
https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/exceptions/
예외 및 예외 처리 - C#
예외 및 예외 처리에 대해 알아봅니다. 이러한 C# 기능은 프로그램이 실행 중일 때 발생하는 예기치 않거나 예외적인 상황을 처리하는 데 도움이 됩니다.
learn.microsoft.com
https://learn.microsoft.com/ko-kr/dotnet/standard/exceptions/exception-class-and-properties
Exception 클래스 및 속성 - .NET
자세히 알아보기: 예외 클래스 및 속성
learn.microsoft.com
* 리플렉션(Reflection)
실행 중(Run Time)에 코드의 구조 정보(메타 데이터)를 탐색하거나 조작하는 기능
[주로 어디에 쓰일까?]
클래스 정보 확인
Type 객체를 통해 클래스 이름, 네임스페이스, 필드, 메서드, 속성 등의 정보를 런타임에 확인할 수 있음
동적으로 메서드 호출
문자열로 받은 메서드 이름을 기반으로 런타임에 해당 메서드를 실행
어셈블리 로딩
어셈블리(DLL)를 런타임에 동적으로 메모리에 로딩(주의 - 컴파일 시점 아님)
속성 값 읽기/설정
PropertyInfo를 통해 객체의 프로퍼티(Get/Set 메서드로 구성된 속성) 값을 런타임에 읽거나 변경 가능
커스텀 어트리뷰트
클래스, 필드 메서드 등에 붙은 [Attribute] 메타데이터를 런타임에 읽고 기능 제어에 활용
[단점 및 주의점]
런타임 해석 기반이라 일반 메서드 호출보다 느림
컴파일 타임 타입 검사 불가 → 타입 안정성 낮음
일반 로직에서는 남용을 피하고,
도구 제작 또는 유틸리티 용도에서 주로 활용할 수 있음
ㄴ [활용 예시] Unity
* 애트리뷰트(Attribute)
런타임에 읽을 수 있는 메타데이터(주석과 유사한 구조)
다양한 프레임워크에서 기능 제어 및 자동화의 도구로 쓰임
* 애트리뷰트 사용 예시
애트리뷰트 | 역할 |
[Obsolete] | 경고 메시지 출력 (경고: 이 함수는 곧 제거됩니다) |
[Serializable] | 직렬화 지원 명시 |
[Range(0, 10)] | Unity에서 Inspector UI 제어 |
[HttpGet], [Route("api/user")] | ASP.NET에서 라우팅 처리 |
[Test] | NUnit에서 테스트로 인식하게 만듦 |
* 널러블(nullable)
기본적으로 null을 가질 수 없는 값 형식에 null을 허용하기 위한 타입
* 널 병합 연산자(null-coalescing operator)
??
null일 때, 오른쪽 값을 반환
??=
null일 때, 오른쪽 값을 할당
* 널 조건 연산자(null-conditional operator)
객체?.멤버
null 아니면 멤버 접근
객체?.메서드()
null 아니면 메서드 호출
'게임프로그래밍 > Unity_C#' 카테고리의 다른 글
[MMORPG 게임 개발(C#, Unity)] Part 3. 유니티 기초 (0) | 2025.04.15 |
---|---|
[MMORPG 게임 개발(C#, Unity)] Part 3. 환경 설정 (0) | 2025.04.15 |
[MMORPG 게임 개발(C#, Unity)] Part 1. 객체 지향 (0) | 2025.04.10 |
[MMORPG 게임 개발(C#, Unity)] Part 1. 데이터 처리, 코드의 흐름 제어 (0) | 2025.04.09 |
[MMORPG 게임 개발(C#, Unity)] Part 1. 환경설정, 프로그래밍 OT (0) | 2025.04.07 |