no image
C# - C#과 .NET의 시작, 개발 환경 구축과 Hello World
📘 챕터 1. C# 소개와 개발 환경 설정🧩 C# 언어의 개요C#은 마이크로소프트에서 개발한 객체지향 프로그래밍 언어이다.형식에 엄격하며, 안전성과 효율성을 고려한 구조를 갖추고 있다.C, C++, Java와 유사한 문법을 기반으로 하며, 다양한 플랫폼에서 실행 가능하다.주요 특징객체지향 설계: 모든 구성 요소가 클래스와 객체 기반으로 이루어진다.강한 형식 시스템: 자료형을 명확히 선언해야 하며, 컴파일 타임에 오류를 방지할 수 있다.가비지 컬렉션 지원: 메모리 해제를 자동으로 처리한다.플랫폼 독립성: .NET 플랫폼을 기반으로 다양한 환경에서 실행 가능하다.🛠️ .NET 프레임워크.NET은 C# 프로그램이 실행되는 기반 플랫폼이다.C#으로 작성된 코드는 중간 언어(IL)로 먼저 컴파일되며, 실행 ..
2025.07.07
C#
no image
C# - Adpater Pattern2 C# 코드예제
❓ 어댑터 패턴에대한 이해도가 부족한거 같아서 다시 GPT에게 물어봐서 다시 공부해봤다. namespace로 Adpater를 정의해야 하는 줄 알았는데 그렇지 않았다. 결론은 🎯 결론C#에서 어댑터 패턴은 "직접 클래스와 인터페이스로 구현"하는 것이지, 키워드나 특별한 기능이 있는 건 아니야. ✅오..이건 굉장히 새로운 지식이였다 그냥 클래스와 인터페이스로 구현하는거지 딱히 키워드가 있는게 아니였다새로운사실! 그래서 한 번 예제 코드로 보겠다!INewAttack.cspublic interface INewAttack{ void DoAttack();} IOldAttack.cspublic interface IOldAttack{ void SlashAttack();} OldSwordAttack.csp..
2025.07.06
C#
no image
WIL - 본 캠프 1주차(25.06.30~07.05)
지난 일주일 동안 가장 인상 깊었던 배움에는 뭐가 있었지?이번 주는 정말 많은 내용을 다뤘고, 그 중에서도 개념적으로는 C#의 메모리 구조, 클래스 설계, 디자인 패턴, 실무적으로는 Unity의 컴포넌트 이해 및 Git 협업 흐름이 깊이 있게 와닿은 한 주였다.✅ C#/CS 기본기 정리object 타입이 힙에 저장된다는 구조부터 박싱/언박싱, Queue/Stack의 저장 방식까지 메모리 흐름을 코드와 그림으로 함께 정리함HashTable, Dictionary, HashSet, Generics의 차이와 사용처 학습delegate, Func, Action, 람다식의 기본 사용법을 정리하고 함수형 프로그래밍 기초에 접근base, virtual, override, abstract의 의미와 쓰임새를 학습하면서 템..
2025.07.05
no image
TIL - 내일배움캠프 5일차 TIL [디자인 패턴 + CS공부](25.07.04)
🌅 오전 (09:00 ~ 13:00)Unity & C# 학습object 타입과 메모리 구조 (박싱/언박싱)Queue, Stack의 차이 및 힙 저장 방식delegate, Func, => 문법어댑터 패턴 이론 및 Unity 캐릭터 예제namespace Adapter의 의미와 활용🌇 오후 (13:00 ~ 18:00)13:00 ~ 14:00 : 점심시간 🍽️14:00 ~ 16:00 : 프로젝트 발표 🎤16:00 ~ 16:30 : 쉬는 시간16:30 ~ 17:30 : TIL 작성법 강의 📝17:30 ~ 18:00 : 개인 시간🌙 저녁 (18:00 ~ 21:00)18:00 ~ 19:00 : 저녁시간19:00 ~ 21:00 : 친구와 공부 👭오전공부 복습! & 친구가 공부한거 같이 복습!1. 오늘 학습..
2025.07.04
no image
DesignPattern - Adapter Pattern(어댑터 패턴) + 예제
✅ 어댑터 패턴이란?서로 다른 인터페이스를 가진 두 클래스가 함께 동작하도록 중간에 "변환기" 역할을 해주는 패턴📌 한 줄 요약:"호환되지 않는 인터페이스를 연결해주는 중간 어댑터 클래스"✅ 언제 쓰일까?기존 코드 or 라이브러리 인터페이스를 바꾸지 않고 사용하고 싶을 때인터페이스 불일치 때문에 직접 호출이 안 될 때예전 코드와 새로운 코드를 자연스럽게 연결하고 싶을 때✅ 예제 시나리오: 충전기 어댑터한국 콘센트는 220V미국 전자제품은 110V어댑터를 끼우면 한국 콘센트에 미국 기기를 연결할 수 있어!✅ C# 코드 예제1️⃣ 기존 시스템 (한국 방식)interface ITarget{ void Request(); // 우리가 원하는 방식}class KoreanCharger : ITarget{ ..
2025.07.04
no image
C# - goto
✅ goto란?goto는 프로그램의 흐름을 특정 위치(레이블)로 "강제로" 이동시키는 문법이야.goto 레이블이름;...레이블이름: 실행할 코드;✅ 아주 단순히 말하면:"코드 중간 어딘가로 점프!"✅ 간단한 예제int i = 0;start:Console.WriteLine(i);i++;if (i 🟰 위 코드는 사실상 while문처럼 동작해.✅ goto는 언제 쓰나?switch문에서 중첩된 case 건너뛸 때에러 발생 시 빠르게 특정 cleanup으로 이동매우 드물게 복잡한 상태 머신 구조✅ switch문에서의 goto int num = 2;switch (num){ case 1: Console.WriteLine("One"); break; case 2: ..
2025.07.04
C#
no image
C# - Delegate(델리게이트) + Lambda operator(람다 연산자) + Lambda(람다식)
✅ 델리게이트(Delegate)란?📌 델리게이트는 메서드를 참조할 수 있는 타입이다.쉽게 말하면, **"함수를 변수처럼 다루기 위한 문법"**이야.C#에서 함수 자체는 변수에 담을 수 없지만,델리게이트를 통해 **함수(메서드)를 가리키는 참조(주소)**를 저장하고 호출할 수 있어.✅ 왜 쓸까?델리게이트는 다음과 같은 상황에서 유용해:콜백 함수 구현이벤트(Event) 처리전략(Strategy) 패턴처럼 동작의 유연한 교체다형성 없이 다양한 함수 호출 처리✅ 델리게이트 기본 선언 및 사용// 1. 델리게이트 선언delegate void PrintDelegate(string message);// 2. 사용할 메서드void PrintHello(string msg){ Console.WriteLine("He..
2025.07.04
C#
no image
C# - Queue(큐) vs Stack(스택) + 메모리구조
✅ 핵심 차이 한 줄 요약자료구조개념큐(Queue)FIFO: 먼저 들어간 게 먼저 나온다 (First-In First-Out)스택(Stack)LIFO: 나중에 들어간 게 먼저 나온다 (Last-In First-Out)✅ 실생활 비유자료구조비유 예시Queue줄 서기, 은행 번호표, 프린터 대기열Stack책 쌓기, 접시 쌓기, 웹 브라우저 뒤로가기✅ C# 예제 코드📌 QueueQueue q = new Queue();q.Enqueue("철수");q.Enqueue("영희");Console.WriteLine(q.Dequeue()); // 철수Enqueue() : 데이터 넣기Dequeue() : 가장 먼저 들어온 데이터 꺼내기📌 StackStack s = new Stack();s.Push("철수");s.Push..
2025.07.04
C#
반응형

📘 챕터 1. C# 소개와 개발 환경 설정


🧩 C# 언어의 개요

C#은 마이크로소프트에서 개발한 객체지향 프로그래밍 언어이다.
형식에 엄격하며, 안전성과 효율성을 고려한 구조를 갖추고 있다.
C, C++, Java와 유사한 문법을 기반으로 하며, 다양한 플랫폼에서 실행 가능하다.

주요 특징

  • 객체지향 설계: 모든 구성 요소가 클래스와 객체 기반으로 이루어진다.
  • 강한 형식 시스템: 자료형을 명확히 선언해야 하며, 컴파일 타임에 오류를 방지할 수 있다.
  • 가비지 컬렉션 지원: 메모리 해제를 자동으로 처리한다.
  • 플랫폼 독립성: .NET 플랫폼을 기반으로 다양한 환경에서 실행 가능하다.

🛠️ .NET 프레임워크

.NET은 C# 프로그램이 실행되는 기반 플랫폼이다.
C#으로 작성된 코드는 중간 언어(IL)로 먼저 컴파일되며, 실행 시점에 CLR(Common Language Runtime)이 이를 기계어로 변환하여 실행한다.
이 과정에서 메모리 관리, 예외 처리, 보안 등의 기능을 자동으로 제공받을 수 있다.


💻 Visual Studio 설치 및 프로젝트 생성

Visual Studio는 C# 개발에 가장 널리 사용되는 통합 개발 환경(IDE)이다.

설치 절차

  • Visual Studio 공식 홈페이지에서 설치 파일을 다운로드한다.
  • 설치 시 .NET 데스크톱 개발 워크로드를 선택한다.
  • 설치 완료 후 초기 설정을 진행한다.

콘솔 앱 생성 방법

  • Visual Studio 실행 → 새 프로젝트 만들기
  • C# 콘솔 앱 선택
  • .NET 6.0 선택 + 최상위 문 사용 안함 설정
  • 프로젝트 이름 및 경로 설정 후 생성

🖨️ Hello World 출력하기

아래는 C#으로 작성한 가장 기본적인 콘솔 출력 프로그램이다.

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

구성 요소 설명

  • using System;: Console 클래스 등 기본 기능을 사용하기 위한 선언이다.
  • namespace HelloWorld: 코드 영역을 구분하는 논리적 단위이다.
  • class Program: 실행 로직을 담는 클래스이다.
  • static void Main(string[] args): 프로그램의 진입점이다.
  • Console.WriteLine(...): 콘솔에 문자열을 출력하고 줄바꿈을 포함한다.

⚙️ 자동완성과 보조 기능

Visual Studio는 IntelliSense라는 자동완성 기능과 코드 템플릿 기능을 지원한다.

자동완성

  • Tab 키를 사용해 클래스명이나 메서드명을 자동으로 완성할 수 있다.
  • Ctrl + Space를 누르면 사용 가능한 메서드 목록, 설명, 인자 정보를 확인할 수 있다.

코드 템플릿

  • for, if, while 등 키워드 입력 후 Tab을 두 번 누르면 기본 구조가 자동 생성된다.

📣 강의에서의 학습 태도와 조언

무엇을 배우는가보다 왜 배우는가에 집중해야 한다.
문법을 단순히 외우기보다는 그 목적과 맥락을 이해하는 것이 장기적인 실력으로 이어진다.

또한, 완벽한 코드를 한 번에 작성하는 것보다 빠르게 시도하고 실패하면서 수정하는 경험이 중요하다.
많이 써보고, 직접 에러를 겪고 해결하면서 성장할 수 있다.

 

사실 기초는 이미 알고있지만 다시 상기 시킨다는 목적으로 하나씩 다시 공부해봐야겠다. 개발자는 겸손할 수 밖에 없는 직업이기 때문에 항상 겸손하자..

반응형
반응형

어댑터 패턴에대한 이해도가 부족한거 같아서 다시 GPT에게 물어봐서 다시 공부해봤다. namespace로 Adpater를 정의해야

하는 줄 알았는데 그렇지 않았다. 결론은 

🎯 결론

C#에서 어댑터 패턴은 "직접 클래스와 인터페이스로 구현"하는 것이지, 키워드나 특별한 기능이 있는 건 아니야.

 

오..이건 굉장히 새로운 지식이였다 그냥 클래스와 인터페이스로 구현하는거지 딱히 키워드가 있는게 아니였다

새로운사실! 그래서 한 번 예제 코드로 보겠다!

INewAttack.cs

public interface INewAttack
{
    void DoAttack();
}

 

IOldAttack.cs

public interface IOldAttack
{
    void SlashAttack();
}

 

OldSwordAttack.cs

public class OldSwordAttack : IOldAttack
{
    public void SlashAttack()
    {
        Console.WriteLine("Old sword slashes the enemy!");
    }
}

 

OldSwordAdapter.cs

public class OldSwordAdapter : INewAttack
{
    private readonly IOldAttack _oldAttack;

    public OldSwordAdapter(IOldAttack oldAttack)
    {
        _oldAttack = oldAttack;
    }

    public void DoAttack()
    {
        // 새 인터페이스를 통해 기존 메서드를 호출
        _oldAttack.SlashAttack();
    }
}

 

Program.cs

using System;

class Program
{
    static void Main(string[] args)
    {
        // 레거시 시스템
        IOldAttack oldAttack = new OldSwordAttack();

        // 어댑터를 통해 새 시스템에 연결
        INewAttack adaptedAttack = new OldSwordAdapter(oldAttack);

        // 새 시스템의 인터페이스 사용
        adaptedAttack.DoAttack();
    }
}

💡 요약

  • INewAttack: 새 클라이언트 인터페이스
  • IOldAttack + OldSwordAttack: 레거시 시스템
  • OldSwordAdapter: 어댑터 클래스
  • Program.cs: 어댑터를 통해 새 방식으로 레거시 클래스를 사용하는 예

처음에는 이해가 잘 안됐지만 그래도 이렇게 예제 코드로 보니 이해가 좀 됐다!

그냥 간단히 얘기하자면 예전 시스템을 새로운 시스템이랑 연결을 시켜야 하는데 어댑터 패턴을 쓰지 않는다면

굉장히 복잡해지고 어려워 질 것이다. 그래서 어댑터 패턴을 사용하는 것!

반응형
반응형

지난 일주일 동안 가장 인상 깊었던 배움에는 뭐가 있었지?

이번 주는 정말 많은 내용을 다뤘고, 그 중에서도 개념적으로는 C#의 메모리 구조, 클래스 설계, 디자인 패턴, 실무적으로는 Unity의 컴포넌트 이해 및 Git 협업 흐름이 깊이 있게 와닿은 한 주였다.

✅ C#/CS 기본기 정리

  • object 타입이 힙에 저장된다는 구조부터 박싱/언박싱, Queue/Stack의 저장 방식까지 메모리 흐름을 코드와 그림으로 함께 정리
  • HashTable, Dictionary, HashSet, Generics의 차이와 사용처 학습
  • delegate, Func, Action, 람다식의 기본 사용법을 정리하고 함수형 프로그래밍 기초에 접근
  • base, virtual, override, abstract의 의미와 쓰임새를 학습하면서 템플릿 메서드 패턴을 적용해보는 실습 진행
  • 일반 오버라이드와 템플릿 메서드 패턴의 차이, 다형성(polymorphism) 개념과 인스턴스 생성(Parent obj = new Child()) 구조를 확인

✅ Unity 실습 및 시스템 이해

  • Unity의 SpriteRenderer 정렬, 스케일 조정, Update 주기, GC 동작 원리 학습
  • Card 시스템 제작: 카드 클릭 제한, 애니메이션 타이밍 조절
  • ScriptableObject의 개념과 실습을 통해 데이터 중심의 Unity 개발 방식에 입문

✅ Git & 협업

  • Git / GitHub / GitHub Desktop을 통한 협업 방식 이해
  • 커밋 → 푸시 → 풀 → 충돌 해결까지 실습
  • Detached HEAD 오류 상황을 경험하고 해결 과정을 통해 감각 증가

✅ 디자인 패턴 적용

  • 어댑터 패턴 개념 학습
  • Unity 기반 예제로 캐릭터 공격 방식 리팩토링 → Adapter 구조로 설계 

 

배움까지 다가가는데 어떤 어려움이 있었지?

  1. 내가 안다고 생각했던 개념이 실제론 정확하지 않았다는 충격
    • 문제정의: object는 값 타입이니까 스택에 저장된다고 착각함. 박싱/언박싱도 그냥 개념적으로만 알고 있었음
    • 시도: 메모리 구조를 직접 그림으로 그리고, object obj = 3;처럼 간단한 코드로 실제 메모리 흐름을 추적
    • 해결방법: object는 참조형이고, 값 타입을 넣는 순간 힙에 복사본이 생긴다는 점을 코드 + 그림 + 디버깅으로 확인
    • 새롭게 알게 된 점: "내가 안다고 생각하는 것"과 "내가 설명할 수 있는 것"은 완전히 다르다
    • 다시 만나게 된다면: 개념을 배울 땐 반드시 구조적 이해 + 코드 테스트 + 직접 설명까지 해보자
  2. 클래스 구조, 오버라이드, 템플릿 메서드 개념 충돌
    • 문제정의: base, override, virtual, abstract를 각각 따로 알긴 했지만, 언제 어떻게 함께 써야 하는지 감이 안 왔음
    • 시도: 공통 동작이 있는 예제(예: 공격 방식, 카드 뒤집기 등)를 가정하고 부모/자식 클래스를 직접 코딩
    • 해결방법: 부모 클래스에서 뼈대를 잡고, 자식 클래스에서 세부 로직만 바꾸는 템플릿 메서드 구조로 정리
    • 새롭게 알게 된 점: 템플릿 메서드는 다형성과 결합돼서 확장 가능한 구조를 만드는 핵심 도구
    • 다시 만나게 된다면: 단순한 오버라이드에 그치지 않고, 유지보수가 쉬운 템플릿 구조로 먼저 생각해보기
  3. Git 협업의 현실적인 문제 - Detached HEAD 겪음
    • 문제정의: GitHub Desktop에서 실수로 커밋하고 보니 HEAD가 브랜치에서 떨어져 있었음
    • 시도: 현재 브랜치 상태 확인 → git checkout -b로 새 브랜치 생성해서 커밋 이력 살리는 방식으로 복구
    • 해결방법: Detached HEAD 개념 파악하고, 협업 전엔 반드시 브랜치 체크하는 습관 만들기
    • 새롭게 알게 된 점: 협업 도구는 단순한 버튼 클릭으로 끝나지 않고, 기초 개념을 알고 써야 문제 발생 시 빠르게 대처할 수 있다
    • 다시 만나게 된다면: 커밋하기 전에 항상 현재 브랜치 상태 확인 / 중요한 작업은 커맨드라인에서 확인까지 병행
  4. ScriptableObject 개념의 진입 장벽
    • 문제정의: MonoBehaviour랑 뭐가 다르고 왜 써야 하는지 감이 안 왔음. 실습이 없으니 더 막막했음
    • 시도: 카드 정보를 ScriptableObject로 분리해보고, 인스펙터에서 직접 값 할당해보며 구조 파악
    • 해결방법: 인스턴스화된 데이터가 아니라, 데이터 자산으로 재사용하는 구조라는 개념을 이해
    • 새롭게 알게 된 점: 반복되거나 확장될 수 있는 데이터는 ScriptableObject로 관리하면 설계가 훨씬 깔끔해짐
    • 다시 만나게 된다면: 데이터 구조를 설계할 때 먼저 "이건 ScriptableObject로 빼도 될까?"부터 고민해보기

 

과정에서 나는 무엇을 깨달았고, 어떤 감정/생각이 들었었지?

  • 이번 주 가장 크게 느낀 건 “나는 생각보다 제대로 모르고 있었구나”였다.
    그동안 익숙하게 쓰던 object, override, abstract 같은 키워드가, 막상 그림으로 설명하거나 메모리 구조로 풀어내려 하니까 하나도 정리가 안 돼 있었다.
    처음엔 그 사실이 좀 충격이었고, 내가 잘 못하고 있다는 생각이 들었다.
  • 그런데 공부를 다시 차근차근 해보면서, 그리고 직접 코드를 짜보고 그림도 그려보니까 하나씩 이해되는 순간이 생겼고, 그때부터는 오히려 재미있어졌다.
    “아 내가 이래서 이걸 잘못 쓰고 있었구나”, “이게 그래서 이렇게 동작했구나” 같은 실마리가 계속 풀리면서 '아는 척'이 아니라 진짜 이해하게 된다는 감각이 생겼다.
  • 특히 Git에서 Detached HEAD 상황을 겪으면서 “아 도구도 개념 없이 쓰면 이렇게 꼬이는구나” 하는 깨달음이 컸고, 앞으로는 아무리 익숙한 거라도 구조부터 짚고 가야겠다는 생각이 들었다.
  • 또 하나 느낀 건, "무조건 혼자 해결하려고 하지 말자"는 거였다.
    모르는 걸 질문하고, 회고로 정리하고, 팀원과 공유하면서 되려 더 빠르게 개념이 정리됐고, 나만의 언어로 정리하고 설명하는 연습이 진짜 중요하다는 걸 깨달았다.
  • 솔직히 이번 주엔 조금 지치기도 했지만. 하루에 배우는 양도 많고, 헷갈리는 것도 많았는데, 그만큼 내가 단단해지고 있다는 느낌도 분명 있었다. 생각보다 너무 즐거웠고 좋은, 재밌는 시간이였다!
    “모르는 게 많다”는 걸 부끄러워하지 않고, “그걸 계속 알아가는 중이다”라고 생각하기로 했다!

💬 메모 [팀에 대한 감사와 나 자신에 대한 믿음]

이번 주는 스파르타 코딩클럽 1주차가 마무리된 시점이기도 하고, 함께했던 팀원들과 헤어지는 시간이기도 했다.
비록 한 주 동안의 짧은 만남이었지만, 팀원들과의 시간이 너무 소중했고, 각자의 자리에서 열심히 해준 모든 분들에게 진심으로 감사한 마음이 크다.

매니저님은 팀장이 그냥 말뿐인 역할이라고 했지만, 나는 한 명 한 명을 진심으로 챙기고 싶은 마음이 더 컸다.
불화 없이 함께 잘 지내고 싶었고, 누가 힘들어도 옆에 있어주고 싶었다. 나는 그런 팀장이 되고 싶었다.
그런 마음을 팀원들도 알아줬을진 모르겠지만 팀원들에게 고마운 한 주였다.
이별이 아쉽지만, 또 다른 팀에서 언젠가 다시 만날 수 있다는 생각에 기대도 된다.

 

또, 학습 측면에서도 스스로에 대해 다시 한번 확인할 수 있었던 시간이었다.
하루 12시간의 집중이 가능할까 걱정도 됐지만, 마음 한편엔 “나는 할 수 있어”라는 믿음이 있었다.
그 믿음은 어머니가 늘 해주시던 말, “너는 하면 제대로 하는 사람이야”라는 말에서 왔고, 지금의 나를 만든 힘이기도 하다.
늘 믿어주고 응원해주는 우리 가족에게도 이번 기회를 통해 다시 한번 감사함을 느꼈다.

앞으로 배워야 할 것도, 겪어야 할 것도 많지만
나는 잘 해낼 수 있다.
그리고, 점점 더 기대된다. 앞으로도 잘 해보자아!!!!
화이팅!! 오예!!!

📅 이번 주 TIL 목록

 

본 캠프 1일차 [OT + 새로운 팀 + 팀 프로젝트(카드 뒤집기 게임)]

1. 오늘 하루 계획오전09:00 ~ 12:00 : OT12:00 ~ 13:00 : 12조 회의오늘 계획 (Task)[x] 팀원들 각자 역할 정하기[x] 필수 기능 기획 작성[x] 이미지 올리기오후13:00 ~ 14:00 : 점심시간14:00 ~ 15:30 : Git 사용법 특강

dev-jen.tistory.com

 

본 캠프 2일차 [CS공부 + 카드게임 팀 프로젝트]

1. 오늘 학습 키워드Unity, Card 시스템, 애니메이션 제한, 클릭 제한, Git 협업, Detached HEAD, ScriptableObject 개념, Update 주기, GC, 캡슐화2. 오늘 학습 한 내용을 나만의 언어로 정리하기 오전에는 컴퓨터

dev-jen.tistory.com

 

본 캠프 3일차 [CS공부 + 카드게임 팀 프로젝트]

오늘 하루 계획오전09:00 ~ 13:00 : CS 공부어제 내용 복습 - GC, 해시테이블, 딕셔너리, .NET 런타임, 캡슐화, 박싱/언박싱 & 형변환HashTableDictionaryHashSet제네릭 (Generics)ScriptableObject오후13:00 ~ 14:00 : 점심

dev-jen.tistory.com

 

본 캠프 4일차 [디자인 패턴 + CS공부]

하루 계획오전09:00 ~ 13:00 : CS 공부, 디자인 패턴어제 내용 복습 - 자료구조, ScriptableObject, 해시셋, 해시테이블, 딕셔너리base 키워드virtual / override / abstract템플릿 메서드 패턴일반 오버라이드 vs 템

dev-jen.tistory.com

 

본 캠프 5일차 [디자인 패턴 + CS공부]

🌅 오전 (09:00 ~ 13:00)Unity & C# 학습object 타입과 메모리 구조 (박싱/언박싱)Queue, Stack의 차이 및 힙 저장 방식delegate, Func, => 문법어댑터 패턴 이론 및 Unity 캐릭터 예제namespace Adapter의 의미와 활용🌇

dev-jen.tistory.com

 

📅 이번 주 Study 목록

 

C# Unity - 가비지 컬렉터(GC) 자동실행기준

✅ 가비지 컬렉터(GC)의 역할이란?더 이상 사용되지 않는 힙의 메모리를 자동으로 찾아서 정리해주는 시스템즉,메모리 누수 방지수동으로 메모리 해제하지 않아도 됨 (delete, free 필요 없음)✅ GC

dev-jen.tistory.com

 

C# - 박싱/언박싱과 박싱/언박싱&형변환 차이

✅ 박싱(Boxing) & 언박싱(Unboxing)🔸 박싱(Boxing)값 형식(Value Type) 데이터를 **참조 형식(Reference Type)**으로 변환하는 것값 타입(예: int, float)을 object 타입에 저장하면 박싱이 발생이 과정에서 값이 힙

dev-jen.tistory.com

 

C# - 캡슐화

✅ 캡슐화(Encapsulation)란?"객체의 내부 상태(데이터)를 외부로부터 숨기고, 허용된 방식으로만 접근하도록 제한하는 것."✅ 핵심 요약항목설명목적데이터를 보호하고, 잘못된 접근/수정을 방지수

dev-jen.tistory.com

 

Unity - Update(), FixedUpdate(), LateUpdate()

✅ Unity의 3가지 주요 루프 함수함수 이름실행 주기용도특징Update()매 프레임마다사용자 입력, 일반 로직프레임 속도에 따라 실행 빈도 달라짐 (가변)FixedUpdate()고정 시간 간격마다물리 연산 (Rigidb

dev-jen.tistory.com

 

C# - .NET Runtime

✅ .NET 런타임이란?.NET Runtime은 C#, F#, VB.NET 같은 **.NET 언어로 만든 프로그램을 실행해주는 "실행 환경(엔진)"**이야.다시 말해, .NET 코드가 컴퓨터에서 실제로 돌아가도록 도와주는 핵심 소프트웨

dev-jen.tistory.com

 

C# - 해시테이블(HashTable) vs 딕셔너리(Dictionary)&제네릭(Generic)

✅ 해시테이블 (Hash Table)📌 개념키(key)를 해시 함수(Hash Function)에 넣어 나온 해시값을 기반으로 데이터를 저장하는 자료구조.내부적으로는 배열(array)와 연결 리스트 또는 트리 구조를 함께 사용

dev-jen.tistory.com

 

Unity - 스크립터블오브젝트(ScriptableObject)&예제

✅ ScriptableObject란?📌 개념 정리ScriptableObject는 MonoBehaviour처럼 Unity에서 사용하는 클래스지만,씬에 붙는 컴포넌트가 아니고, 독립적인 데이터 객체야.데이터를 자산(Asset)으로 만들어 저장하고 공

dev-jen.tistory.com

 

C# - 해쉬셋(HashSet) vs Dictionary(HashTable)

✅ HashSet이란?중복을 허용하지 않는 데이터 집합 (Set)을 구현한 자료구조내부적으로는 **해시 테이블(Hash Table)**을 사용하지만,핵심 목적은 **"중복 없는 값의 모음"**을 만드는 거야.🔍 HashSet의

dev-jen.tistory.com

 

C# - 자료구조

✅ 자료구조란?자료(데이터)를 효율적으로 저장하고, 관리하고, 사용할 수 있도록 구성한 방식쉽게 말하면,"데이터를 어떻게 정리해서 넣고, 꺼내고, 수정할지에 대한 규칙과 구조"✅ 왜 중요한

dev-jen.tistory.com

 

C# - Virtual & abstract

✅ virtual 키워드 정리📌 정의virtual은 부모 클래스에서 메서드나 속성을 "재정의 가능"하게 만드는 키워드입니다.📋 기본 문법class Parent{ public virtual void SayHello() { Console.WriteLine("안녕하세요. 부

dev-jen.tistory.com

 

C# - Class Inheritance(클래스 상속)& Interface(인터페이스) vs abstract Class

✅ 클래스 상속 (Inheritance)✔️ 정의class A : B처럼, 한 클래스가 다른 클래스의 기능을 물려받는 것✔️ 목적코드 재사용: 부모 클래스의 멤버(필드, 메서드 등)를 자식이 그대로 사용 가능기능 확

dev-jen.tistory.com

 

Unity - Template Method Pattern(템플릿 메서드 패턴) vs virtual

✅ 템플릿 메서드 패턴이란?**템플릿 메서드 패턴(Template Method Pattern)**은상속을 기반으로 부모 클래스에서 **알고리즘의 전체 흐름(틀)**을 정의하고,일부 단계는 abstract 또는 virtual로 정의하여 자

dev-jen.tistory.com

 

C# - base 키워드

✅ base 키워드란?자식 클래스에서 부모 클래스의 생성자나 메서드, 필드에 접근할 때 사용하는 키워드📌 1. 부모 클래스의 메서드 호출할 때class Parent{ public void Speak() { Console.WriteLine("부모가 말

dev-jen.tistory.com

 

C# - Parent obj = new Child(); 메모리는 어떻게 될까? & 다형성

Parent obj = new Child(); 메모리는 어떻게 될까?🤔 질문클래스 상속을 사용할 때,Parent obj = new Child();이렇게 부모 타입으로 자식 객체를 참조하면,메모리는 부모 클래스만큼만 잡히는 걸까? 아니면 자

dev-jen.tistory.com

 

C# - Object Type(오브젝트 타입) & Object Memori(오브젝트 메모리 설명)

✅ object 타입이란?C#에서 object는 모든 타입의 최상위(Base) 타입이야.다시 말해, C#의 모든 타입은 object를 상속받고 있어.int, string, float, bool, DateTime, 사용자 정의 클래스 등 전부 다 object형으로 취

dev-jen.tistory.com

 

C# - Collection(컬렉션)

✅ 컬렉션이란?"여러 데이터를 하나로 묶어 저장할 수 있는 자료구조 클래스"→ C#에서는 System.Collections, System.Collections.Generic 네임스페이스 아래에서 제공돼.✅ 컬렉션의 종류 (중요한 것들만 정

dev-jen.tistory.com

 

C# - List vs Array(리스트 vs 배열)

✅ 리스트(List) vs 배열(Array) 핵심 차이 요약항목배열 (int[])리스트 (List)크기고정 (정적)가변 (동적)타입기본 자료형 (int[])제네릭 클래스 (List)기능제한적 (Add 불가)다양한 메서드 제공 (Add, Remove 등

dev-jen.tistory.com

 

C# - Queue(큐) vs Stack(스택) + 메모리구조

✅ 핵심 차이 한 줄 요약자료구조개념큐(Queue)FIFO: 먼저 들어간 게 먼저 나온다 (First-In First-Out)스택(Stack)LIFO: 나중에 들어간 게 먼저 나온다 (Last-In First-Out)✅ 실생활 비유자료구조비유 예시Queue줄

dev-jen.tistory.com

 

C# - Delegate(델리게이트) + Lambda operator(람다 연산자) + Lambda(람다식)

✅ 델리게이트(Delegate)란?📌 델리게이트는 메서드를 참조할 수 있는 타입이다.쉽게 말하면, **"함수를 변수처럼 다루기 위한 문법"**이야.C#에서 함수 자체는 변수에 담을 수 없지만,델리게이트를

dev-jen.tistory.com

 

C# - goto

✅ goto란?goto는 프로그램의 흐름을 특정 위치(레이블)로 "강제로" 이동시키는 문법이야.goto 레이블이름;...레이블이름: 실행할 코드;✅ 아주 단순히 말하면:"코드 중간 어딘가로 점프!"✅ 간단한

dev-jen.tistory.com

 

Unity - Adapter Pattern(어댑터 패턴) + 예제

✅ 어댑터 패턴이란?서로 다른 인터페이스를 가진 두 클래스가 함께 동작하도록 중간에 "변환기" 역할을 해주는 패턴📌 한 줄 요약:"호환되지 않는 인터페이스를 연결해주는 중간 어댑터 클래

dev-jen.tistory.com

 

 

 

 

 

반응형
반응형

🌅 오전 (09:00 ~ 13:00)

  • Unity & C# 학습
    • object 타입과 메모리 구조 (박싱/언박싱)
    • Queue, Stack의 차이 및 힙 저장 방식
    • delegate, Func, => 문법
    • 어댑터 패턴 이론 및 Unity 캐릭터 예제
    • namespace Adapter의 의미와 활용

🌇 오후 (13:00 ~ 18:00)

  • 13:00 ~ 14:00 : 점심시간 🍽️
  • 14:00 ~ 16:00 : 프로젝트 발표 🎤
  • 16:00 ~ 16:30 : 쉬는 시간
  • 16:30 ~ 17:30 : TIL 작성법 강의 📝
  • 17:30 ~ 18:00 : 개인 시간

🌙 저녁 (18:00 ~ 21:00)

  • 18:00 ~ 19:00 : 저녁시간
  • 19:00 ~ 21:00 : 친구와 공부 👭
    • 오전공부 복습! & 친구가 공부한거 같이 복습!

1. 오늘 학습 키워드

  • object 타입과 메모리 구조
  • 박싱(Boxing) / 언박싱(Unboxing)
  • Queue, Stack 저장 방식
  • delegate, Func, Action, 람다식 (=>)
  • 어댑터 패턴(Adapter Pattern)
  • Unity 어댑터 예제 (캐릭터 공격 방식)
  • namespace Adapter

2. 오늘 학습 한 내용을 나만의 언어로 정리하기

 

https://dev-jen.tistory.com/entry/C-Object-Type%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%ED%83%80%EC%9E%85-Object-Memori%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%EB%A9%94%EB%AA%A8%EB%A6%AC

 

C# - Object Type(오브젝트 타입) & Object Memori(오브젝트 메모리 설명)

✅ object 타입이란?C#에서 object는 모든 타입의 최상위(Base) 타입이야.다시 말해, C#의 모든 타입은 object를 상속받고 있어.int, string, float, bool, DateTime, 사용자 정의 클래스 등 전부 다 object형으로 취

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/C-Collection%EC%BB%AC%EB%A0%89%EC%85%98

 

C# - Collection(컬렉션)

✅ 컬렉션이란?"여러 데이터를 하나로 묶어 저장할 수 있는 자료구조 클래스"→ C#에서는 System.Collections, System.Collections.Generic 네임스페이스 아래에서 제공돼.✅ 컬렉션의 종류 (중요한 것들만 정

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/C-List-vs-Array%EB%A6%AC%EC%8A%A4%ED%8A%B8-vs-%EB%B0%B0%EC%97%B4

 

C# - List vs Array(리스트 vs 배열)

✅ 리스트(List) vs 배열(Array) 핵심 차이 요약항목배열 (int[])리스트 (List)크기고정 (정적)가변 (동적)타입기본 자료형 (int[])제네릭 클래스 (List)기능제한적 (Add 불가)다양한 메서드 제공 (Add, Remove 등

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/C-Queue%ED%81%90-vs-Stack%EC%8A%A4%ED%83%9D-%EB%A9%94%EB%AA%A8%EB%A6%AC%EA%B5%AC%EC%A1%B0

 

C# - Queue(큐) vs Stack(스택) + 메모리구조

✅ 핵심 차이 한 줄 요약자료구조개념큐(Queue)FIFO: 먼저 들어간 게 먼저 나온다 (First-In First-Out)스택(Stack)LIFO: 나중에 들어간 게 먼저 나온다 (Last-In First-Out)✅ 실생활 비유자료구조비유 예시Queue줄

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/C-Delegate%EB%8D%B8%EB%A6%AC%EA%B2%8C%EC%9D%B4%ED%8A%B8-Lambda-operator%EB%9E%8C%EB%8B%A4-%EC%97%B0%EC%82%B0%EC%9E%90-Lambda%EB%9E%8C%EB%8B%A4%EC%8B%9D

 

C# - Delegate(델리게이트) + Lambda operator(람다 연산자) + Lambda(람다식)

✅ 델리게이트(Delegate)란?📌 델리게이트는 메서드를 참조할 수 있는 타입이다.쉽게 말하면, **"함수를 변수처럼 다루기 위한 문법"**이야.C#에서 함수 자체는 변수에 담을 수 없지만,델리게이트를

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/C-goto

 

C# - goto

✅ goto란?goto는 프로그램의 흐름을 특정 위치(레이블)로 "강제로" 이동시키는 문법이야.goto 레이블이름;...레이블이름: 실행할 코드;✅ 아주 단순히 말하면:"코드 중간 어딘가로 점프!"✅ 간단한

dev-jen.tistory.com

https://dev-jen.tistory.com/entry/Unity-Adapter-Pattern%EC%96%B4%EB%8C%91%ED%84%B0-%ED%8C%A8%ED%84%B4-%EC%98%88%EC%A0%9C

 

Unity - Adapter Pattern(어댑터 패턴) + 예제

✅ 어댑터 패턴이란?서로 다른 인터페이스를 가진 두 클래스가 함께 동작하도록 중간에 "변환기" 역할을 해주는 패턴📌 한 줄 요약:"호환되지 않는 인터페이스를 연결해주는 중간 어댑터 클래

dev-jen.tistory.com

  • object는 모든 타입의 부모이고, 값 타입을 참조 타입처럼 다룰 수 있게 해준다. 하지만 이 과정에서 박싱/언박싱이 일어나 성능상 주의가 필요하다. 박싱된 값은 힙에 저장되며, 언박싱은 스택에 다시 값을 복사하는 것이다.
  • Queue와 Stack은 모두 힙에 저장되며, Queue는 먼저 들어온 데이터를 먼저 꺼내는 구조(FIFO), Stack은 나중에 들어온 걸 먼저 꺼내는 구조(LIFO)다. 사용 목적에 따라 구분해서 써야 하며, 둘 다 내부적으로 배열을 사용해 구현된다.
  • delegate는 함수를 참조하는 타입으로, 코드의 흐름을 더 유연하게 만들 수 있다. 특히 Func, Action, Predicate 같은 제네릭 델리게이트는 선언을 줄이고 람다식과 조합해서 자주 쓰인다.
  • =>는 람다식 문법으로, "입력값이 이렇게 동작한다"는 의미로 사용된다. 익명 함수를 간결하게 표현할 수 있어 LINQ나 이벤트 처리에 자주 활용된다.
  • 어댑터 패턴은 서로 호환되지 않는 클래스 구조를 중간에서 연결해주는 구조로, 기존 코드를 건드리지 않고 외부 시스템을 도입할 수 있게 해준다. Unity에서도 IEnemy를 기준으로 LegacyOrcAdapter를 만들어 외부 클래스와 호환성을 유지하는 예제를 직접 구현해보았다.
  • namespace Adapter처럼 네임스페이스를 적절히 나누면 구조가 명확해지고 클래스 충돌을 피할 수 있다. 특히 프로젝트 규모가 커질수록 네임스페이스 정리는 필수다.

3. 학습하며 겪었던 문제점 & 에러

1. object와 메모리 구조 헷갈림

  • 문제정의: object는 값 타입일 때 스택에 저장된다고 오해함
  • 시도: 그림을 통해 힙/스택 구조 확인
  • 해결방법: object도 참조 타입이기 때문에 박싱 시 힙에 저장됨을 학습
  • 새롭게 알게 된 점: object 타입의 변수는 실제 데이터를 힙에 저장하고, 변수에는 주소가 들어간다
  • 다시 만나게 된다면: 메모리 구조를 항상 그림으로 함께 확인할 것

2. 어댑터 패턴 예시가 추상적으로 느껴졌음

  • 문제정의: 입력 시스템 예제는 너무 복잡하게 느껴짐
  • 시도: 캐릭터 공격 구조 예제로 변경해서 이해
  • 해결방법: IEnemy → Goblin, LegacyOrcAdapter → LegacyOrc 예제로 쉽게 이해
  • 새롭게 알게 된 점: 인터페이스 기반 설계의 유연성과 어댑터 패턴의 실용성
  • 다시 만나게 된다면: 복잡한 구조는 단순한 예제로 바꿔서 학습할 것 & 유니티 예제로 학습

3. delegate와 Func의 시그니처 이해 부족

  • 문제정의: Func<int, int, int>는 뭘 의미하는지 처음에 감이 안 옴
  • 시도: 문법 구조 분석 → 매개변수와 반환값이 어떤 역할인지 학습
  • 해결방법: Func<매개변수1, 매개변수2, 반환값> 구조임을 알게 됨
  • 새롭게 알게 된 점: Func<int, int, int>는 int a, int b를 받아서 int를 반환하는 함수
  • 다시 만나게 된다면: 직접 함수 시그니처를 풀어 쓰면서 이해할 것

4. 람다식의 => 문법 생소함

  • 문제정의: => 기호가 무슨 의미인지, 어떤 구조인지 혼란스러웠음
  • 시도: 일반 함수와 비교하면서 람다식을 해석
  • 해결방법: =>는 "이렇게 동작한다"는 의미로, 익명 함수 정의임을 이해
  • 새롭게 알게 된 점: 람다식은 익명 함수이며, delegate나 Func에 바로 넣어 쓸 수 있음
  • 다시 만나게 된다면: 기존 함수 → 람다식 변환 예제를 더 연습할 것

5. Queue와 Stack의 저장 위치 오해

  • 문제정의: 큐/스택이 스택 메모리에 저장된다고 착각
  • 시도: 힙/스택 구조 그림을 통해 확인
  • 해결방법: Queue<T>, Stack<T>는 참조 타입이라 힙에 저장됨을 명확히 이해
  • 새롭게 알게 된 점: 내부에 배열을 가지며, 그 배열도 힙에 저장됨
  • 다시 만나게 된다면: 스택/힙 구조를 항상 객체 기준으로 생각할 것

4. 메모

오늘 오전에도 원래 알던것들도 있었지만 처음 배웠던것도 있었다! 앞으로도 공부했던것들 잘 복습하면서 하나하나 잘 배워가자 이번 월~금을 지내며 솔직히 내가 이렇게까지 하게될줄 몰랐다 공부를 공부라고 생각하기보단 하나씩 의문점을 가지고 생각하고 하다보니 12시간이 너무 금방갔다 시작하기전에는 “말이 12시간이지 당연히 쉽지 않겠지” 라고 생각했지만 막상 공부시간등등을 생각하지않고 진행하다보니 너무 시간이 빨랐다. 앞으로의 시간도 너무 기대된다!

 

오늘 저녁에는 대학교를 같이 다녔던 5조의 혜현이라는 친구와 같이 오늘 오전에 공부했던걸 각자 얘기하며 공부했다 나는 확실히 혼자 하는 것 보단 소통하며 서로 뭘 알았고 이해했는지, 뭘 모르고 있었는지 서로 얘기하며 토론하는 식의 공부를 굉장히 좋아한다. 앞으로도 계속 잘 응용해보며 열심히 공부해보자아ㅏ!!!!

 

이번 1주차 팀 프로젝트를 진행하면서 팀원들도 너무 좋은 팀원들을 만나서 너무 즐겁게 같이 개발했는데 다음주면 다른 팀으로 바뀐다니 너무 아쉬웠다 저번 사전캠프 팀도 좋은 분들을 만나서 좋았었는데 항상 마지막이되면 너무 아쉽다..

뭐 아예 헤어지는건 아니니깐! 그래도 또 새로운 좋은 인연들이 많을거라고 생각한다! 앞으로의 인연들을 기대하면서 하루하루 열심히 해보자!!! 오예!!!

반응형
반응형

✅ 어댑터 패턴이란?

서로 다른 인터페이스를 가진 두 클래스가 함께 동작하도록 중간에 "변환기" 역할을 해주는 패턴

📌 한 줄 요약:
"호환되지 않는 인터페이스를 연결해주는 중간 어댑터 클래스"


✅ 언제 쓰일까?

  • 기존 코드 or 라이브러리 인터페이스를 바꾸지 않고 사용하고 싶을 때
  • 인터페이스 불일치 때문에 직접 호출이 안 될 때
  • 예전 코드와 새로운 코드를 자연스럽게 연결하고 싶을 때

✅ 예제 시나리오: 충전기 어댑터

  • 한국 콘센트는 220V
  • 미국 전자제품은 110V

어댑터를 끼우면 한국 콘센트에 미국 기기를 연결할 수 있어!


✅ C# 코드 예제

1️⃣ 기존 시스템 (한국 방식)

interface ITarget
{
    void Request();  // 우리가 원하는 방식
}

class KoreanCharger : ITarget
{
    public void Request()
    {
        Console.WriteLine("220V로 충전합니다.");
    }
}

2️⃣ 호환되지 않는 외부 클래스 (미국 방식)

 
class AmericanDevice
{
    public void ConnectWith110V()
    {
        Console.WriteLine("110V에 연결되었습니다.");
    }
}

3️⃣ 어댑터 클래스

class Adapter : ITarget
{
    private AmericanDevice _device;

    public Adapter(AmericanDevice device)
    {
        _device = device;
    }

    public void Request()
    {
        // 220V 요청을 110V 방식으로 변환
        _device.ConnectWith110V();
    }
}

4️⃣ 사용 코드

ITarget charger1 = new KoreanCharger();
charger1.Request(); // ✅ 220V로 충전합니다.

ITarget charger2 = new Adapter(new AmericanDevice());
charger2.Request(); // ✅ 110V에 연결되었습니다.

✅ 구조 요약 (클래스 관계)

[ITarget] <─── [Adapter] ───> [AmericanDevice]
          ↑
[KoreanCharger] (직접 구현)

✅ 어댑터 패턴 종류

방식 설명
객체 어댑터 어댑터가 기존 객체를 포함해서 호출 (💡 C#에서 주로 사용)
클래스 어댑터 어댑터가 상속을 통해 연결 (C#은 다중 상속 안 되므로 제한적)
 

✅ 실제 사용 예 (Unity에서도 유용)

  • Unity의 InputSystem이 바뀌었을 때, 기존 방식과 연결할 때
  • 외부 API 라이브러리와 내부 구조 연결할 때
  • 레거시 시스템 유지하면서 새 구조 연동할 때

✅ 요약

항목 설명
목적 서로 다른 인터페이스를 연결
키워드 "변환기", "중간 연결자"
구조 기존 인터페이스 + 어댑터 클래스 + 호환 불가 객체
실용성 외부 시스템 통합, 레거시 코드 연동 시 유용

 

흠..이렇게 봐서는 어댑터 패턴이 얼마나 중요한지 아직은 잘 모르겠다 좀 더 자세한 예시 코드를 보자.

일단 어댑터를 사용하는 방법을 제대로 알아보죠!

 

✅ 1. namespace Adapter가 왜 등장할까?

🔸 namespace는 이름 충돌을 방지하고 코드를 구조적으로 정리하기 위한 C#의 기능이야.

예를 들어, 이런 상황 생각해봐:

// Game 안에 있는 Enemy
namespace Game
{
    public class Enemy { }
}

// 외부에서 받아온 LegacyEnemy도 Enemy 클래스가 있음
namespace Legacy
{
    public class Enemy { }
}

이런 경우 Enemy가 둘이라 충돌해.
그래서 Game.Enemy, Legacy.Enemy처럼 네임스페이스를 명시해줘야 돼.


✅ 2. 어댑터 쓸 때도 마찬가지

보통 어댑터 코드는 별도의 Adapter 네임스페이스 안에 넣어 정리해.

namespace Adapter
{
    public class LegacyEnemyAdapter : MonoBehaviour, IEnemy
    {
        ...
    }
}

그리고 다른 코드에서 사용할 때는 이렇게 써:

using Adapter;

// 또는 명시적으로 접근
Adapter.LegacyEnemyAdapter adapter = new Adapter.LegacyEnemyAdapter();

✅ 3. 언제 Adapter.를 붙여야 할까?

상황 설명
using Adapter; 있음 그냥 LegacyEnemyAdapter 라고만 써도 됨
using Adapter; 없음 Adapter.LegacyEnemyAdapter 이렇게 전체 경로로 써야 함
이름 충돌 있을 때 반드시 Adapter. 붙여서 명확하게 구분해야 함
 

✅ Unity에서 실제로는?

Unity에서는 대부분 클래스가 MonoBehaviour를 상속하고
스크립트를 오브젝트에 붙여서 인스펙터에서 연결하니까
Adapter.LegacyEnemyAdapter 라고 직접 쓰는 일은 드물어.

하지만 코드에서 직접 생성하거나, 네임스페이스 충돌이 있을 땐 명시적으로 써줘야 해:

IEnemy enemy = new Adapter.LegacyEnemyAdapter();

✅ 한 줄 요약

어댑터 클래스를 namespace Adapter 안에 넣으면
구조를 명확히 하고, 다른 클래스 이름과 충돌하지 않게 도와준다.
필요할 땐 Adapter.ClassName 으로 명시적으로 접근하면 된다.

 

실제로 어댑터를 사용할때는 namespace를 사용하는듯합니다.

그리고 어댑터가 적용된거는 using으로만 작성해도 충분한듯해요!

다음 어댑터 제대로된 예제 코드를 보죠!

 

🎮 예제 시나리오:

우리 게임은 IInputHandler 라는 인터페이스로 입력을 처리하고 있음.
하지만 외부에서 제공된 LegacyInput 클래스는 우리가 쓰는 구조와 다름.
→ 어댑터를 만들어서 LegacyInput을 IInputHandler처럼 사용할 수 있도록 하자.


✅ 1. 인터페이스: 우리가 사용하는 입력 방식

// IInputHandler.cs
public interface IInputHandler
{
    void HandleInput();
}

✅ 2. 정상적인 Unity 입력 구현 (키보드로 움직임)

// KeyboardInputHandler.cs
using UnityEngine;

public class KeyboardInputHandler : MonoBehaviour, IInputHandler
{
    public void HandleInput()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("스페이스바 눌림 (키보드)");
        }
    }
}

✅ 3. 외부에서 가져온 입력 시스템 (호환 안 됨)

// LegacyInput.cs
using UnityEngine;

public class LegacyInput
{
    public bool IsTouched()
    {
        // 가상의 외부 입력 방식 (예: 터치스크린)
        return Input.touchCount > 0;
    }
}

✅ 4. 어댑터 클래스 만들기

// Adapter/LegacyInputAdapter.cs
using UnityEngine;
using AdapterNamespace;

namespace AdapterNamespace
{
    public class LegacyInputAdapter : MonoBehaviour, IInputHandler
    {
        private LegacyInput _legacyInput;

        private void Awake()
        {
            _legacyInput = new LegacyInput();
        }

        public void HandleInput()
        {
            if (_legacyInput.IsTouched())
            {
                Debug.Log("터치 입력 감지됨 (어댑터)");
            }
        }
    }
}

✅ 5. 플레이어 컨트롤러 — 어댑터든 키보드든 상관 없이 처리 가능!

// Player.cs
using UnityEngine;

public class Player : MonoBehaviour
{
    public MonoBehaviour inputSource;

    private IInputHandler _inputHandler;

    private void Start()
    {
        _inputHandler = inputSource as IInputHandler;

        if (_inputHandler == null)
        {
            Debug.LogError("inputSource는 IInputHandler를 구현해야 합니다!");
        }
    }

    private void Update()
    {
        _inputHandler?.HandleInput();
    }
}

✅ Unity 인스펙터 설정

  1. Player 오브젝트에 Player.cs 컴포넌트 추가
  2. inputSource 슬롯에 아래 중 하나를 드래그:
    • KeyboardInputHandler 컴포넌트 붙인 오브젝트
    • LegacyInputAdapter 컴포넌트 붙인 오브젝트

➡️ 어떤 걸 연결해도 작동 ✅


✅ 결과

연결된 컴포넌트 결과
KeyboardInputHandler 키보드 스페이스 입력 처리
LegacyInputAdapter 터치 입력 처리 (외부 시스템)
 

✅ 요약 구조

[Player] → IInputHandler ← [KeyboardInputHandler]
                          ← [LegacyInputAdapter → LegacyInput]
  • LegacyInput 은 우리가 바꿀 수 없는 외부 시스템
  • LegacyInputAdapter 가 어댑터 역할
  • Player 입장에선 어떤 입력 시스템이든 같은 방식으로 처리함

이렇게 예제 코드로 예시를 들어봤는데요 흠.. 사실 저도 아직까지 막 와닿진 않네요 ㅠㅜ

다음에 유니티로 직접 개발해봐야겠습니다! 사실 직접해보는게 제일 빠르고 이해가 좋은거같아요!

반응형

C# - goto

Dev_Jen
|2025. 7. 4. 11:39
반응형

✅ goto란?

goto는 프로그램의 흐름을 특정 위치(레이블)로 "강제로" 이동시키는 문법이야.

goto 레이블이름;
...
레이블이름:
    실행할 코드;

✅ 아주 단순히 말하면:

"코드 중간 어딘가로 점프!"


✅ 간단한 예제

int i = 0;

start:
Console.WriteLine(i);
i++;

if (i < 5)
    goto start;  // start로 이동 (반복처럼 동작)

🟰 위 코드는 사실상 while문처럼 동작해.


✅ goto는 언제 쓰나?

  • switch문에서 중첩된 case 건너뛸 때
  • 에러 발생 시 빠르게 특정 cleanup으로 이동
  • 매우 드물게 복잡한 상태 머신 구조

✅ switch문에서의 goto

 
int num = 2;

switch (num)
{
    case 1:
        Console.WriteLine("One");
        break;
    case 2:
        Console.WriteLine("Two");
        goto case 1; // case 1으로 이동!
    default:
        Console.WriteLine("Default");
        break;
}

📝 출력:

Two  
One

✅ 사용 시 주의사항 ❗

  • goto는 코드를 복잡하게 만들고,
  • 흐름을 예측하기 어렵게 만들기 때문에
  • 되도록 사용하지 않는 것이 원칙이야

📌 대부분의 경우 for, while, if로 해결 가능!


✅ 요약 정리

항목 설명
goto 코드의 흐름을 특정 지점으로 강제 이동
사용처 switch case 점프, 에러 처리, 특별한 상황
추천 여부 ❌ 일반 코드에서는 사용 자제
대체 if, while, return, break, continue 등

✅ 한 줄 요약

goto는 레이블로 점프하는 문법이지만, 가독성 나빠서 정말 필요한 상황에서만 조심스럽게 사용해야 한다.

 

C에서 배웠어서 원래 알고있는 내용이였지만 C#에도 있는줄은 몰랐다 ㅎㅎ..

아무래도 원하는곳으로 이동할 수 있게 만들어주지만 너무 많이 사용하게되면 코드가 복잡해지고 왔다갔다해서 더 이상해질수도 있을듯하다. 사용한다면 정말 중요한 부분에만 사용하는걸로..

반응형
반응형

✅ 델리게이트(Delegate)란?

📌 델리게이트는 메서드를 참조할 수 있는 타입이다.
쉽게 말하면, **"함수를 변수처럼 다루기 위한 문법"**이야.

C#에서 함수 자체는 변수에 담을 수 없지만,
델리게이트를 통해 **함수(메서드)를 가리키는 참조(주소)**를 저장하고 호출할 수 있어.


✅ 왜 쓸까?

델리게이트는 다음과 같은 상황에서 유용해:

  • 콜백 함수 구현
  • 이벤트(Event) 처리
  • 전략(Strategy) 패턴처럼 동작의 유연한 교체
  • 다형성 없이 다양한 함수 호출 처리

✅ 델리게이트 기본 선언 및 사용

// 1. 델리게이트 선언
delegate void PrintDelegate(string message);

// 2. 사용할 메서드
void PrintHello(string msg)
{
    Console.WriteLine("Hello " + msg);
}

// 3. 델리게이트 변수 생성 및 할당
PrintDelegate printer = PrintHello;

// 4. 델리게이트 호출 (함수처럼 사용 가능)
printer("재은"); // Hello 재은

✅ 델리게이트의 중요한 특징

특징 설명
형식 안전 델리게이트는 선언된 시그니처(매개변수 타입, 반환형)를 따라야 함
멀티 캐스트 가능 여러 메서드를 델리게이트에 연결할 수 있음 (+=, -=)
익명 함수, 람다와 호환 delegate 키워드 또는 lambda 표현식으로 할당 가능

✅ 익명 메서드 & 람다식으로 쓰기

🔸 익명 메서드

PrintDelegate printer = delegate(string msg)
{
    Console.WriteLine("Hello " + msg);
};

🔸 람다식

PrintDelegate printer = (msg) => Console.WriteLine("Hello " + msg);

✅ 델리게이트 종류

종류 설명
일반 델리게이트 위에서 직접 선언한 것
Action<T> 반환값이 없는 델리게이트 (void)
Func<T, TResult> 반환값이 있는 델리게이트
Predicate<T> bool을 반환하는 델리게이트

✅ Action, Func, Predicate 예시

 
Action<string> sayHi = (name) => Console.WriteLine($"Hi, {name}");
Func<int, int, int> sum = (a, b) => a + b;
Predicate<int> isEven = (num) => num % 2 == 0;

sayHi("재은");          // Hi, 재은
Console.WriteLine(sum(3, 5));  // 8
Console.WriteLine(isEven(4));  // true

✅ 멀티캐스트 델리게이트 (여러 메서드 연결)

delegate void Notifier();
void A() => Console.WriteLine("A 호출");
void B() => Console.WriteLine("B 호출");

Notifier notify = A;
notify += B;

notify(); // A 호출, B 호출

✅ 델리게이트 vs 이벤트

항목 델리게이트 이벤트(Event)
접근 외부에서 자유롭게 호출 가능 외부에서 직접 호출 불가
목적 콜백, 전략 패턴 등 이벤트 처리 전용
사용 위치 일반 메서드 전달 등 주로 UI, 버튼 클릭, 상태 변화

✅ 정리 요약

항목 설명
델리게이트 메서드를 참조할 수 있는 타입
사용 목적 콜백, 이벤트, 유연한 함수 실행
문법 delegate, Action, Func, Predicate
특징 형식 안전, 멀티캐스트 가능, 람다 지원

델리게이트란 함수를 변수처럼 사용하는것도 알겠고 람다식을 이용하면 더 쉽게 잘 사용할 수 있는것도 알겠다 근데

=> 이표시가 무슨 표시인지를 모르겠다.. 물어보니까 람다 연산자라고 하는데 자세히 알아봅시다!

✅ => 는 뭐야?

"goes to", 혹은 "이 함수는 이렇게 작동해!" 라고 해석하면 좋아.

(parameters) => expression_or_statement_block

이 구조는 람다식(lambda expression) 이라고 불리는 문법으로,
익명 함수(이름 없는 함수)를 만들기 위한 간결한 문법이야.


✅ 예시로 설명

Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 5)); // 출력: 8
  • (a, b) → 매개변수
  • => → 람다 연산자
  • a + b → 반환할 표현식 (return 생략 가능)

→ 위 코드는 "a와 b를 받아서 a + b를 반환하는 함수" 를 만들고, add에 담은 거야.

Func<int, int, int> add = (a, b) => a + b;

이 부분이 하나도 이해가 안된다.. 어떻게 저렇게 나온거지?...한번 물어보겠습니다

✅ 코드 다시 보기

Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 5)); // 출력: 8

✅ 이건 무슨 뜻일까?

💡 한 줄 해석:

add라는 이름의 "함수 변수"를 만들고,
이 함수는 int 2개를 받아서 int 하나를 반환하는 함수야.

즉, 이건 아래 함수와 같은 의미야:

int Add(int a, int b)
{
    return a + b;
}

하지만 Func<int, int, int>을 사용하면,
함수를 변수처럼 담아서, 더 유연하게 쓸 수 있어.


✅ 코드 완전 해부

부분 의미
Func<int, int, int> 매개변수 2개 (int, int), 반환값 int인 함수 타입
(a, b) 매개변수
=> 람다 연산자
a + b 반환할 값 (return 생략 가능)

아 이 부분에서 제가 궁금했던 Func<int, int, int>가 나오네요! 매개변수 2개를 사용하는 int인 함수 타입이라고 하네요!!! 

궁금증 해결! 완전 해소됐네여!! 굳!!!!

=> 이 연산자도 그냥 람다 연산자니 외우던지..해야겠네여ㅎㅎ..

근데 확실히 더 코드가 간결해지고 이쁘게 쓸 수 있는듯 하네여


✅ 일반 함수와 비교

// 일반적인 함수 정의
int Add(int a, int b)
{
    return a + b;
}

이걸 변수에 저장해서 쓸 수 있도록 만든 게 바로:

Func<int, int, int> add = (a, b) => a + b;

이제 add(3, 5) 하면 → a=3, b=5 → a + b = 8


✅ 다른 예시로 익혀보기

1️⃣ 문자열 길이 구하는 함수

Func<string, int> getLength = s => s.Length;
Console.WriteLine(getLength("hello")); // 5
  • 매개변수 1개 (string)
  • 반환값: int

2️⃣ 두 수의 곱 구하는 함수

Func<int, int, int> multiply = (x, y) => x * y;
Console.WriteLine(multiply(4, 6)); // 24

3️⃣ 인사 출력하는 Action (반환 없음)

Action<string> greet = name => Console.WriteLine("Hi, " + name);
greet("재은"); // Hi, 재은

✅ 요약

문법 의미
Func<T1, T2, TResult> 입력 T1, T2 → 출력 TResult 함수
Action<T> 입력 T → 반환값 없음 (void)
(x, y) => x + y 람다식으로 함수 정의

✅ 다양한 형태의 예시

1. 표현식 람다 (한 줄)

Func<int, int> square = x => x * x;

→ x를 받아서 x * x를 반환하는 함수


2. 문장 블록 람다 (여러 줄)

Action<string> greet = name => {
    Console.WriteLine("안녕!");
    Console.WriteLine("나는 " + name);
};

→ name을 받아서 여러 문장을 실행하는 함수


✅ 어떤 상황에서 쓰여?

  • 델리게이트에 함수 전달할 때
  • LINQ 쿼리에서 (Where(x => x > 0))
  • 이벤트 핸들러
  • 간단한 콜백 함수

✅ 정리

기호 의미
=> 람다 연산자. "함수 정의는 이렇게!"
(x) => x * 2 x를 받아서 x * 2를 반환하는 함수

이렇게 델리게이트와 람다 연산자에 대해서 알아봤는데여 굉장히 흥미롭고 재밌네요!!ㅎㅎ

궁금증도 풀렸고 재밌는 공부가 됐습니다! 앞으로 유니티 개발할때 자주 사용하면 좋겠네여!

반응형

'C#' 카테고리의 다른 글

C# - Adpater Pattern2 C# 코드예제  (2) 2025.07.06
C# - goto  (0) 2025.07.04
C# - Queue(큐) vs Stack(스택) + 메모리구조  (2) 2025.07.04
C# - List vs Array(리스트 vs 배열)  (1) 2025.07.04
C# - Collection(컬렉션)  (0) 2025.07.04
반응형

✅ 핵심 차이 한 줄 요약

자료구조 개념
큐(Queue) FIFO: 먼저 들어간 게 먼저 나온다 (First-In First-Out)
스택(Stack) LIFO: 나중에 들어간 게 먼저 나온다 (Last-In First-Out)

✅ 실생활 비유

자료구조 비유 예시
Queue 줄 서기, 은행 번호표, 프린터 대기열
Stack 책 쌓기, 접시 쌓기, 웹 브라우저 뒤로가기

✅ C# 예제 코드

📌 Queue

Queue<string> q = new Queue<string>();
q.Enqueue("철수");
q.Enqueue("영희");
Console.WriteLine(q.Dequeue()); // 철수
  • Enqueue() : 데이터 넣기
  • Dequeue() : 가장 먼저 들어온 데이터 꺼내기

📌 Stack

Stack<string> s = new Stack<string>();
s.Push("철수");
s.Push("영희");
Console.WriteLine(s.Pop()); // 영희
  • Push() : 데이터 넣기
  • Pop() : 가장 마지막에 들어온 데이터 꺼내기

✅ 메모리 구조 (예시)

🔸 Queue 구조

Enqueue → [1] [2] [3] → Dequeue
                ↑
              순서대로 나감

🔸 Stack 구조

Push → [1] [2] [3] ← Pop
                ↑
           마지막 값부터 꺼냄

✅ 기능 비교

항목 Queue Stack
삽입 Enqueue Push
제거 Dequeue Pop
최상단 요소 보기 Peek Peek
순서 FIFO LIFO
사용 예 작업 순서 처리, 이벤트 대기열 재귀, 뒤로가기, Undo

✅ 정리 요약

항목 Queue Stack
구조 선입선출 (FIFO) 후입선출 (LIFO)
메서드 Enqueue, Dequeue, Peek Push, Pop, Peek
순서 먼저 넣은 것이 먼저 나감 나중에 넣은 것이 먼저 나감
실생활 예시 줄서기, 은행, 프린터 대기 책 더미, 웹브라우저 뒤로가기

물론 스택과 큐도 힙에 저장되겠지만 더 자세히 알고싶어서 다시 물어봤습니다!

 

✅ 왜 힙에 저장될까?

C#에서 Queue<T>, Stack<T>는 클래스(참조 타입)이기 때문이야.
객체가 생성되면 힙에 올라감, 스택에는 참조(주소값) 만 저장됨.

Queue<int> q = new Queue<int>();
  • q는 스택에 있음 → 참조 변수
  • new Queue<int>() 는 힙에 할당됨 → 실제 Queue 객체

같은 구조가 Stack<T>에도 그대로 적용돼.

GPT가 만들어준 그림인데 Internal Array가 뭔 소리인지 이해가 안되서 다시 물어봤어여ㅎㅎ..

✅ "internal array"란?

Queue<T>나 Stack<T> 같은 컬렉션 클래스는
내부적으로 데이터를 담기 위해 배열(T[ ])을 사용해.
이 배열을 흔히 내부 배열, 또는 백업 배열 (backing array) 라고 부르는데, 영어로는:

  • internal array
  • underlying array
  • backing array

라고 표현할 수 있어. 따라서 표현 자체는 맞는 말이야!

표현 자체는 맞는 말이라고 합니다!


✅ 메모리 구조 예시

 
Queue<int> q = new Queue<int>();
q.Enqueue(10);
[스택]
q ──▶ (힙 주소)

[힙]
Queue 객체
 └─ 내부 배열(int[]) = [10, ...]
  • 내부적으로 배열을 기반으로 구현되어 있음
  • 그 배열(int[]) 역시 힙에 생성됨

📌 즉, 힙 안에 Queue 객체가 있고 → Queue 내부에 배열도 힙에 있음
→ 이걸 "힙 안에 힙" 구조라고도 말할 수 있어.


✅ 한 줄 요약

Queue<T>, Stack<T>는 참조 타입 클래스이므로
실제 데이터와 구조 모두 힙에 저장된다.
스택에는 변수명(q, s 등)의 참조(주소) 만 존재한다.

 

반응형