전체 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Rookiss_CSharp
{
// https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part1?srsltid=AfmBOopkXVxKs-MQPYZkTjEYW-yIDMO5xP7l5hQq0hQasUWhobvyKO6N
// 54강 Generic(일반화)
class Program
{
/*
// 모든 타입을 클래스로 만든다면 비효율적
class MyIntList
{
int[] arr = new int[10];
}
class MyFloatList
{
float[] arr = new float[10];
}
class MyShortList
{
short[] arr = new short[10];
}
*/
/*
class MyList
{
// 박싱, 언박싱이 일어나서 성능상 좋지 못함
object[] arr = new object[10];
}
*/
// Template, Type 약자로 T를 많이 사용
// 일반화 클래스가 됨
// T에 어떠한 값이 와도 작동됨
// class MyList<T> // 인자가 한개일 경우
// class MyList<T, K> // 인자가 여러개일 경우(타입 개수만큼 늘리면 됨)
// C++에는 없는 문법, C#에는 있는 문법임
// 조건 추가 가능
// class MyList<T> where T : struct // 어떠한 T값이든 상관 없지만, 값 형식(int, float, bool, enum, struct)이어야 함
// class MyList<T> where T : class // 어떠한 T값이든 상관 없지만, 참조 형식(class, interface(참조형식), delegate, array(string[], int[] 등)이어야 함
// class MyList<T> where T : new() // 어떠한 인자도 받지않는 기본 생성자가 있어야 함
class MyList<T> where T : Monster // T는 어떤 값이든 넣을 수 있지만, 단 T는 반드시 Monster 클래스 혹은 Monster 클래스를 상속 받아야함(특정 타입에 대한 일반 형식을 만들고 싶을때 사용)
{
T[] arr = new T[10];
public T GetItem(int i)
{
return arr[i];
}
}
// 클래스만이 아니라 함수에도 적용됨
static void Test<T>(T input)
{
}
static void Main(string[] args)
{
// object
// 타입 자체가 object
// 장점 : 어떤 타입이든 다 소화가 가능하다.
// C#에서는 int, string 등이 object를 상속받음
object obj = 3; // 박싱(boxing) = 값 타입 → 힙 객체(조금 더 설명하자만, int는 값 타입이고, object는 참조타입이기에, heap에 객체를 생성하고 int 값을 복사하여 넣고, object가 이를 참조함)
object obj2 = "hello world"; // 문자열(string)은 원래부터 참조 타입 (reference type) => 박싱 발생x
int num = (int)obj; // 언박싱(unboxing) = 힙 객체 → 값 타입
// 언박싱 과정
// 1. 힙에 있는 boxed Int32 객체의 값(3)을 읽음
// 2. 스택에 새로운 int 변수 num을 생성하여 값 3을 복사함
string str = (string)obj2;
// obj2는 원래 string이므로 참조 타입, 박싱된 적 없음.(string은 참조 타입(reference type)이므로 항상 힙(Heap)에 저장됩니다.)
// (string)obj2는 단순한 참조 캐스팅(reference cast).
// 힙 주소만 복사해 가져오는 것일 뿐, 값을 새로 만들거나 복사하지 않음.
// Q) 모든 타입을 object로 하면 되지 않을까요?
// -> object로 하면 느리다는 단점이 있음
int num2 = 3;
// int num2 : stack에 들어가는 복사타입의 변수
// object는 무조건 참조타입으로 동작함
// object obj = 3;
// 내부적으로는 힙에 메모리 할당하여 3이라는 값을 넣음
// int num3 = (int)obj;
// 꺼내 올때는 힙에 있는 숫자를 빼와서 stack에 저장(언박싱(unboxing) = 힙 객체 → 값 타입)
// 즉, 박싱(boxing)과 언박싱(unboxing)은 성능상 느림
// 참고(object랑 var은 전혀 다른 개념)
// var : 뒤에 있는 값을 보고 컴파일러가 추측하는 것
var obj3 = 3;
MyList<int> myIntList = new MyList<int>();
MyList<short> myShortList = new MyList<short>();
int item = myIntList.GetItem(0);
// Test<int>(3);
}
}
}
출처
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문| Rookiss - 인프런 강
현재 평점 4.9점 수강생 6,987명인 강의를 만나보세요. 기초 프로그래밍 지식이 없는 사람들을 위한 C# 프로그래밍 기초 강의입니다. 문법 암기 위주의 수업이 아니라, 최대한 필요한 부분만을 요
www.inflearn.com
54강 Generic(일반화)
'C# > 기본 문법' 카테고리의 다른 글
| C# Property(프로퍼티) (0) | 2025.12.14 |
|---|---|
| C# Interface(인터페이스) (0) | 2025.12.14 |
| C# Dictionary (0) | 2025.11.20 |
| C# List (0) | 2025.11.20 |
| C# 다차원 배열, GetLength() (0) | 2025.11.20 |