[ ์น์ 1. ๋ฐ์ดํฐ ๊ฐ๊ณ ๋๊ธฐ ]
# 2์ง์, 10์ง์, 16์ง์
- 10์ง์ : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ...
- 2์ง์ : 0b0, 0b1, 0b10, 0b11, 0b100, 0b101, 0b110, 0b111, 0b1000, 0b1001 ...
- 16์ง์ : 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ...
~> 2์ง์๋ฅผ 4๊ฐ์ฉ ๋์ด์ ํํ
- ์ฆ, int hp = 100 (10์ง์), int hp = 0b01100100 (2์ง์), int hp = 0x64 (16์ง์) ๋ชจ๋ ๊ฐ์ ๊ฐ์ ๋์ ํ๋ ๊ฒ์ด๋ค.
# ์ ์ ๋ฒ์์ ๋น๋ฐ
- ์ต์์ Bit๋ ๋ถํธ Bit์ ํด๋นํ๋ฉฐ, ๋๋ถ๋ถ์ System์์๋ 2์ ๋ณด์๋ฒ์ ํตํด ์์๋ฅผ ํํํ๋ค.
# float
- ์ปดํจํฐ๋ ๋ถ๋ ์์์ (float / double)์ ์ต๋ํ์ ๊ทผ์ฐจ์ ๊ฐ์ผ๋ก ํํํ๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ์ ํํ์ง ์์ ์ ์๋ค.
- float๋ 4Byte ์๊น์ง ํํํ ์ ์๊ณ , double์ 8Byte ์๊น์ง ํํํ ์ ์๋ค.
~> double์ด float์ ๋นํด ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ์ง๋ง, ์ซ์๋ฅผ ๋ณด๋ค ๋ ์ ๋ฐํ๊ฒ ํํํ ์ ์๋ค.
~> ์ค์ ๋ค์ f๋ฅผ ๋ถ์ผ ๊ฒฝ์ฐ float, ๋ถ์ด์ง ์์ ๊ฒฝ์ฐ double๋ก ์ธ์ํ๋ค.
# ์คํธ๋ง ํฌ๋งท
- int, float, short, double ๋ฑ์ Type๋ค์ ( )๋ฅผ ํตํด Casting์ด ๊ฐ๋ฅํ๋ค.
~> int a, short b ๊ฐ ์์๋ b = (short)a ๋ฅผ ํตํด Casting ํ ์ ์๋ค.
~> ํ์ง๋ง string Type์ int a, string b ๊ฐ ์์๋ b = (string)a ์ ๊ฐ์ด ( )๋ฅผ ํตํด Casting ํ ์ ์๋ค.
์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ์ ๋ฐ๊ธฐ ์ํ ๋ฐฉ๋ฒnamespace CSharpStudy { class Program { static void Main(string[] args) { string input = Console.ReadLine(); // Enter๋ฅผ ๋๋ฅด๋ ์๊ฐ์ ๋ณ์์ ์ ์ฅ๋๋ค. Console.WriteLine(); } } }โ
์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ ๋ฐ์ string์ int๋ก Casting ํ๋ ๋ฐฉ๋ฒnamespace CSharpStudy { class Program { static void Main(string[] args) { int number; string input = Console.ReadLine(); // Enter๋ฅผ ๋๋ฅด๋ ์๊ฐ์ ๋ณ์์ ์ ์ฅ๋๋ค. number = int.Parse(input); Console.WriteLine(); } } }โโ
String Format ๋ฐฉ์namespace CSharpStudy { class Program { static void Main(string[] args) { int hp = 80; int maxHp = 100; string msg = string.Format("๋น์ ์ HP๋ {0}/{1} ์ ๋๋ค.", hp, maxHp); Console.WriteLine(msg); } } }โโ
String Interpolation ๋ฐฉ์namespace CSharpStudy { class Program { static void Main(string[] args) { int hp = 100; int maxHp = 100; // ์๋ฐํ ๋งํ๋ฉด Casting๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ๊ธด ํ๋ค. string msg = $"๋น์ ์ HP๋ {hp}/{maxHp} ์ ๋๋ค."; Console.WriteLine(msg); } } }โ
# ์ฐ์ ์ฐ์ฐ
์ผํญ ์ฐ์ฐ์ ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { int number = 25; bool isPair = ((number % 2 == 0) ? true : false); } } }โโ
# ๋ฐ์ดํฐ ๋ง๋ฌด๋ฆฌ
- var Keyword๋ฅผ ํตํ ๋ณ์ ์ ์ธ์ Type์ ์ง์ ์ ์ธํ ๊ฒ์ฒ๋ผ ์ปดํ์ผ๋ฌ๊ฐ ์ถ๋ก ์ ํตํด Type ์ ๊ฒฐ์ ํด์ค๋ค.
~> var a = 10, var b = 4.14f, var c = "Hello", var d = true;
~> ๊ทธ๋ฌ๋ ๊ฐ๋ ์ฑ์ ์ํด Type์ ์ง์ ๋ช ์ํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
[ ์น์
2. ์ฝ๋์ ํ๋ฆ ์ ์ด ]
# switch
- switch๋ฌธ์ if/else๋ฌธ์ ๋นํด ์์ฉ ๋ฒ์๊ฐ ๋์ง ์๋ค.
- ์ด๋ค case๋ฌธ์๋ ํด๋น๋์ง ์์ ๊ฒฝ์ฐ default๋ฌธ์ด ์คํ๋๋ค.
- case๋ฌธ์๋ ๋ฐ๋์ ๋ณ์๊ฐ ์๋ ์์๋ฅผ ๋ฃ์ด์ผ ํ๋ค.
switch๋ฌธ ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { int choice = 0; // 0: ๊ฐ์, 1: ๋ฐ์, 2: ๋ณด, 3: ์นํธํค switch (choice) { case 0: Console.WriteLine("๊ฐ์์ ๋๋ค."); break; case 1: Console.WriteLine("๋ฐ์์ ๋๋ค."); break; case 2: Console.WriteLine("๋ณด์ ๋๋ค."); break; case 3: Console.WriteLine("์นํฌํฐ์ ๋๋ค."); break; default: Console.WriteLine("๋ค ์คํจํ์ต๋๋ค."); break; } } } }โโ
# ๊ฐ์-๋ฐ์-๋ณด ๊ฒ์
๊ฐ๋จํ ๊ฐ์-๋ฐ์-๋ณด ๊ฒ์ ๊ตฌํ #1namespace CSharpStudy { class Program { static void Main(string[] args) { // 0: ๊ฐ์, 1: ๋ฐ์, 2: ๋ณด Random rand = new Random(); int aiChoice = rand.Next(0, 3); // 0 ~ 2 ์ฌ์ด์ ๋๋ค ๊ฐ int choice = Convert.ToInt32(Console.ReadLine()); // ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ ๋ฐ์ ๊ฐ์ ์ซ์๋ก ๋ณํํ์ฌ ๋์ switch (choice) { case 0: Console.WriteLine("๋น์ ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case 1: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case 2: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } switch (aiChoice) { case 0: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case 1: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case 2: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } if (choice == 0) { if (aiChoice == 0) Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); else if (aiChoice == 1) Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); else Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); } else if (choice == 1) { if (aiChoice == 0) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (aiChoice == 1) Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); else Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); } else { if (aiChoice == 0) Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); else if (aiChoice == 1) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); } } } }โโ
๊ฐ๋จํ ๊ฐ์-๋ฐ์-๋ณด ๊ฒ์ ๊ตฌํ #2namespace CSharpStudy { class Program { static void Main(string[] args) { // 0: ๊ฐ์, 1: ๋ฐ์, 2: ๋ณด Random rand = new Random(); int aiChoice = rand.Next(0, 3); // 0 ~ 2 ์ฌ์ด์ ๋๋ค ๊ฐ int choice = Convert.ToInt32(Console.ReadLine()); // ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ ๋ฐ์ ๊ฐ์ ์ซ์๋ก ๋ณํํ์ฌ ๋์ switch (choice) { case 0: Console.WriteLine("๋น์ ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case 1: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case 2: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } switch (aiChoice) { case 0: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case 1: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case 2: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } if (choice == aiChoice) Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); else if (choice == 0 && aiChoice == 2) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == 1 && aiChoice == 0) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == 2 && aiChoice == 1) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); } } }โโ
# ์์์ ์ด๊ฑฐํ
- const Keyword๋ฅผ ํตํด ์์ ํ๋ ๋๋ ๋ก์ปฌ ์์๋ฅผ ์ ์ธํ ์ ์๋ค.
- enum Keyword๋ ์ด๊ฑฐํ ์์๋ฅผ ํํํ๊ธฐ ์ํ ๊ฒ์ผ๋ก ์ด๋ฅผ ํตํด ์์ ์ซ์๋ค์ ๋ณด๋ค ์๋ฏธ์๋ ๋จ์ด๋ค๋ก ํํํ ์ ์๋ค.
~> ๊ฐ๋ ์ฑ ์ธก๋ฉด์์ ๋์์ด ๋๋ค.
~> ๋ณ๋์ ์ง์ ์ด ์์ ๊ฒฝ์ฐ ์ฒซ๋ฒ์งธ ์์๋ 0, ๋๋ฒ์งธ ์์๋ 1 ๋ฑ๊ณผ ๊ฐ์ด 1์ฉ ์ฆ๊ฐ๋ ๊ฐ๋ค์ ํ ๋น๋ฐ๋๋ค.
์์๋ฅผ ํตํ ๊ฐ์-๋ฐ์-๋ณด ๊ฒ์ ์์ namespace CSharpStudy { class Program { static void Main(string[] args) { const int ROCK = 1; const int PAPER = 2; const int SCISSORS = 0; Random rand = new Random(); int aiChoice = rand.Next(0, 3); // 0 ~ 2 ์ฌ์ด์ ๋๋ค ๊ฐ int choice = Convert.ToInt32(Console.ReadLine()); // ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ ๋ฐ์ ๊ฐ์ ์ซ์๋ก ๋ณํํ์ฌ ๋์ switch (choice) { case SCISSORS: Console.WriteLine("๋น์ ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case ROCK: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case PAPER: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } switch (aiChoice) { case SCISSORS: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case ROCK: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case PAPER: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } if (choice == aiChoice) Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); else if (choice == SCISSORS && aiChoice == PAPER) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == ROCK && aiChoice == SCISSORS) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == PAPER && aiChoice == ROCK) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); } } }โโ
์ด๊ฑฐํ์ ํตํ ๊ฐ์-๋ฐ์-๋ณด ๊ฒ์ ์์ namespace CSharpStudy { class Program { enum Choice // ๋ช ์์ ์ผ๋ก ๊ฐ์ ์ ์ธํ์ง ์์ ๊ฒฝ์ฐ 0๋ถํฐ ์์ { Rock = 1, Paper = 2, Scissors = 0 } static void Main(string[] args) { Random rand = new Random(); int aiChoice = rand.Next(0, 3); // 0 ~ 2 ์ฌ์ด์ ๋๋ค ๊ฐ int choice = Convert.ToInt32(Console.ReadLine()); // ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ ๋ฐ์ ๊ฐ์ ์ซ์๋ก ๋ณํํ์ฌ ๋์ switch (choice) { case (int)Choice.Scissors: Console.WriteLine("๋น์ ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case (int)Choice.Rock: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case (int)Choice.Paper: Console.WriteLine("๋น์ ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } switch (aiChoice) { case (int)Choice.Scissors: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๊ฐ์์ ๋๋ค."); break; case (int)Choice.Rock: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ฐ์์ ๋๋ค."); break; case (int)Choice.Paper: Console.WriteLine("์ปดํจํฐ์ ์ ํ์ ๋ณด์ ๋๋ค."); break; } if (choice == aiChoice) Console.WriteLine("๋ฌด์น๋ถ์ ๋๋ค."); else if (choice == (int)Choice.Scissors && aiChoice == (int)Choice.Paper) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == (int)Choice.Rock && aiChoice == (int)Choice.Scissors) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else if (choice == (int)Choice.Paper && aiChoice == (int)Choice.Rock) Console.WriteLine("์น๋ฆฌ์ ๋๋ค."); else Console.WriteLine("ํจ๋ฐฐ์ ๋๋ค."); } } }โโ
# while
do while๋ฌธ ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { string answer; // y๋ฅผ ์ ๋ ฅํ ๋๊น์ง ๋ฌดํํ ๋ฐ๋ณต do { Console.WriteLine("๊ฐ์ฌ๋์ ์์๊ธฐ์ จ๋์? (y/n) : "); answer = Console.ReadLine(); } while (answer != "y"); Console.WriteLine("์ ๋ต์ ๋๋ค!"); } } }โโ
# ref, out
- ๊ธฐ๋ณธ์ ์ผ๋ก C#์ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ๋ call by value (๊ฐ ์ ๋ฌ) ์ ํ๋ค.
~> ์ด๋ ref Keyword๋ฅผ ํตํด ๋ช ์์ ์ผ๋ก call by reference (์ฐธ์กฐ ์ ๋ฌ)์ ํ ์ ์๋ค.
ref Keyword ์์ฉnamespace CSharpStudy { class Program { static void AddOne (ref int num) { num = num + 1; } static void Main(string[] args) { int a = 0; Program.AddOne(ref a); // ๊ฐ์ Class ๋ด์ ํจ์๋ฅผ ํธ์ถ์ Program ์๋ต ๊ฐ๋ฅ Console.WriteLine(a); } } }โ
- out Keyword๋ ๋งค๊ฐ๋ณ์ ํ์ ์๋ก ๋ณ์๊ฐ ์ฐธ์กฐ๋ก ์ ๋ฌ์ด ๋๋ค.
~> out Keyword๋ฅผ ์ฌ์ฉํ ๋งค๊ฐ๋ณ์๋ ํจ์ ๋ด๋ถ์์ ๋ฐ๋์ ๊ฐ์ ์ด๊ธฐํ ์์ผ์ค์ผ ํ๋ค.
~> ์ฌ๋ฌ๊ฐ์ ๊ฐ์ ๋ฐํํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ค.
out Keyword ์์ฉnamespace CSharpStudy { class Program { // result1๋ ๋ชซ, result2๋ ๋๋จธ์ง static void Divide(int a, int b, out int result1, out int result2) { result1 = a / b; result2 = a % b; } static void Main(string[] args) { int num1 = 10; int num2 = 3; int result1; int result2; Divide(10, 3, out result1, out result2); Console.WriteLine(result1); Console.WriteLine(result2); } } }โ
# ์ค๋ฒ๋ก๋ฉ
- ์ค๋ฒ๋ก๋ฉ์ ์ฌ์ ์ ์๋ฏธ๋ "๊ณผ์ ํ๋ค" ์ด๋ฉฐ, ๊ฐ๋จํ๊ฒ ๋งํ๋ฉด ํจ์ ์ด๋ฆ์ ์ฌ์ฌ์ฉ์ด๋ค.
~> ์ค๋ฒ๋ก๋ฉ์ ํ๋์ ๋ฉ์๋์ ์ฌ๋ฌ๊ฐ์ ๊ตฌํ์ ๊ณผ์ ํ ์ ์๋ค.
~> ์ค๋ฒ๋ก๋ฉ์ ๊ฐ์ ๋ฉ์๋ ์ด๋ฆ์ผ๋ก ๋งค๊ฐ๋ณ์์ ๊ฐ์, Type์ ๋ค๋ฅด๊ฒ ์ ์ํ ์ ์๋ค.
~> ๋ฐํ ๊ฐ์ ์ค๋ฒ๋ก๋ฉ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค. (์ฆ, ๋ฐํ๊ฐ๋ง ๋ฌ๋ฆฌ ํ ๊ฒฝ์ฐ ์ค๋ฒ๋ก๋ฉ X)
์ค๋ฒ๋ก๋ฉ ์์ฉnamespace CSharpStudy { class Program { // ํจ์ ์ด๋ฆ์ ์ฌ์ฌ์ฉ static int Add(int a, int b) { return a + b; } static int Add(int a, int b, int c) { return a + b + c; } static float Add(float a, float b) { return a + b; } static void Main(string[] args) { int result = Program.Add(2, 3); float result2 = Program.Add(2.0f, 3.0f); } } }โ
- ์ ํ์ ๋งค๊ฐ๋ณ์๋ ๋งค๊ฐ ๋ณ์๋ฅผ ํ์ ๋๋ ์ ํ ์ฌํญ์ผ๋ก ์ง์ ํ ์ ์๋ค.
์ ํ์ ๋งค๊ฐ๋ณ์ ์์ฉ #1namespace CSharpStudy { class Program { // ์ ํ์ ๋งค๊ฐ๋ณ์ static int Add(int a, int b, int c = 0) { return a + b + c; } static void Main(string[] args) { int result = Program.Add(1, 2); int result2 = Program.Add(1, 2, 3); } } }โ
์ ํ์ ๋งค๊ฐ๋ณ์ ์์ฉ #2namespace CSharpStudy { class Program { // ์ ํ์ ๋งค๊ฐ๋ณ์ static int Add(int a, int b, int c = 0, float d = 1.0f, double e = 3.0) { return a + b + c; } static void Main(string[] args) { int result = Program.Add(1, 2, d: 2.0f); } } }โ
[ ์น์
3. TextRPG ]
# ๋๋ฒ๊น ๊ธฐ์ด
1. ์ฐ์ ๋ณ์์ ๊ฐ, ๋ฉ๋ชจ๋ฆฌ ๋์ ๋๋ ์ฝ๋ ๋ถ๊ธฐ์ ์คํ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ ์ํด ์คํ ์ค์ธ ์ฝ๋๋ฅผ ์ผ์ ์ค๋จํด์ผ ํ๋ ์์น์ ์ค๋จ์ ์ ์ค์ ํ๋ค.
2. F5๋ฅผ ํตํด ๋๋ฒ๊น ์ ์์ํ ์ ์๊ณ , ๋๋ฒ๊น ์ด ์์๋ ๋ค ๋ ธ๋์ ํ์ดํ๋ ์ผ์ ์ค์ง๋ ๋ฌธ์ ๊ฐ๋ฆฌํจ๋ค.
3. F10์ ํตํด ํ๋ก์์ ๋จ์๋ก ์คํํ ์ ์๊ณ , F11์ ํตํด ์ฝ๋๋ฅผ ํ ๋จ๊ณ์ฉ ์คํํ ์๋ ์๋ค.
~> ํ๋ก์์ ๋ ๋ฉ์๋ (ํจ์) ์ ๊ฐ๋ค. (์ฆ, ์ด๋ค ํจ์๋ฅผ ๋ง๋๋๋ผ๋ ํด๋น ํจ์๋ก ๋ค์ด๊ฐ์ง ๋ง๊ณ ๊ฒฐ๊ณผ๋ง ๋ณด๊ฒ ๋ค๋ ๊ฒ)
๋๋ฒ๊น ์ ํธ์ถ ์คํ์ ํตํด ๊ฒฝ๋ก๋ฅผ ํ์ ํ ์ ์๋ค.
์ค๋จ์ ์ [ ์ค๋ฅธ์ชฝ ๋ง์ฐ์ค ] - [ ์กฐ๊ฑด ] ์ ํตํด ์กฐ๊ฑด์ ์ค์ ํ ์ ์๋ค.
๋๋ฒ๊น ์ ์ค๋จ์ ์์ ๋ ธ๋์ ํ์ดํ๋ฅผ ๋๋๊ทธํ์ฌ ์คํ ์์๋ฅผ ๋ง์๋๋ก ์กฐ์ ํ ์ ์๋ค.
# TextRPG ์ง์ ๊ณ ๋ฅด๊ธฐ
TextRPG ์ง์ ๊ณ ๋ฅด๊ธฐnamespace CSharpStudy { class Program { enum ClassType { None = 0, Knight = 1, Archer = 2, Mage = 3 } static ClassType ChooseClass() { Console.WriteLine("์ง์ ์ ์ ํํ์ธ์!"); Console.WriteLine("[1] ๊ธฐ์ฌ"); Console.WriteLine("[2] ๊ถ์"); Console.WriteLine("[3] ๋ฒ์ฌ"); ClassType choice = ClassType.None; string input = Console.ReadLine(); switch (input) { case "1": choice = ClassType.Knight; break; case "2": choice = ClassType.Archer; break; case "3": choice = ClassType.Mage; break; } return choice; } static void Main(string[] args) { while (true) { ClassType choice = ChooseClass(); if (choice != ClassType.None) break; } } } }โ
# TextRPG ํ๋ ์ด์ด ์์ฑ (๊ตฌ์กฐ์ฒด)
- ๊ตฌ์กฐ์ฒด๋ ํ๋ ์ด์์ ๋ณ์๋ค์ ๋ฌถ์ด์ ๊ทธ๋ฃน์ผ๋ก ๋ง๋๋ ์ฌ์ฉ์ ์ ์ ์๋ฃํ์ด๋ค.
+ ์ถ๊ฐ ๊ฒ์ ( https://usingsystem.tistory.com/6 )
- Class์ ๊ตฌ์กฐ์ฒด์ ์ฐจ์ด์
1. Class๋ Heap ์์ญ์ ํ ๋น๋์ง๋ง, ๊ตฌ์กฐ์ฒด๋ Stack ์์ญ์ ํ ๋น๋๋ค.
2. Class๋ ์ฐธ์กฐ ํ์ ์ด์ง๋ง, ๊ตฌ์กฐ์ฒด๋ ๊ฐ ํ์ ์ด๋ค.
3. Class๋ ์์์ด ๊ฐ๋ฅํ์ง๋ง, ๊ตฌ์กฐ์ฒด๋ ์์์ด ๋ถ๊ฐ๋ฅํ๋ค.
TextRPG ํ๋ ์ด์ด ์์ฑ (๊ตฌ์กฐ์ฒด ์์ฉ)namespace CSharpStudy { class Program { // ... struct Player { public int hp; public int attack; } // ... static void CreatePlayer(ClassType choice, out Player player) { switch (choice) { case ClassType.Knight: player.hp = 100; player.attack = 10; break; case ClassType.Archer: player.hp = 75; player.attack = 12; break; case ClassType.Mage: player.hp = 50; player.attack = 15; break; default: player.hp = 0; player.attack = 0; break; } } static void Main(string[] args) { while (true) { ClassType choice = ChooseClass(); if (choice != ClassType.None) { // ์บ๋ฆญํฐ ์์ฑ Player player; CreatePlayer(choice, out player); } } } } }โ
# TextRPG ๋ชฌ์คํฐ ์์ฑ
TextRPG ๋ชฌ์คํฐ ์์ฑusing System.Diagnostics.Tracing; namespace CSharpStudy { class Program { // ... enum MonsterType { None = 0, Slime = 1, Orc = 2, Skeleton = 3 } struct Monster { public int hp; public int attack; } // ... static void CreateRandomMonster(out Monster monster) { Random rand = new Random(); int randMonster = rand.Next(1, 4); switch (randMonster) { case (int)MonsterType.Slime: Console.WriteLine("์ฌ๋ผ์์ด ์คํฐ๋์์ต๋๋ค!"); monster.hp = 20; monster.attack = 2; break; case (int)MonsterType.Orc: Console.WriteLine("์คํฌ๊ฐ ์คํฐ๋์์ต๋๋ค!"); monster.hp = 40; monster.attack = 4; break; case (int)MonsterType.Skeleton: Console.WriteLine("์ค์ผ๋ ํค์ด ์คํฐ๋์์ต๋๋ค!"); monster.hp = 30; monster.attack = 3; break; default: monster.hp = 0; monster.attack = 0; break; } } static void EnterField() { Console.WriteLine("ํ๋์ ์ ์ํ์ต๋๋ค!"); // ๋๋ค์ผ๋ก 1~3 ๋ชฌ์คํฐ ์ค ํ๋๋ฅผ ์คํฐ Monster monster; CreateRandomMonster(out monster); Console.WriteLine("[1] ์ ํฌ ๋ชจ๋๋ก ๋์ "); Console.WriteLine("[2] ์ผ์ ํ๋ฅ ๋ก ๋ง์๋ก ๋๋ง"); } // ... static void Main(string[] args) { while (true) { ClassType choice = ChooseClass(); if (choice != ClassType.None) { // ์บ๋ฆญํฐ ์์ฑ Player player; CreatePlayer(choice, out player); // ๊ฒ์ ์ ์ฅ EnterGame(); } } } } }โ
# TextRPG ์ ํฌ
TextRPG ์ ํฌusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { // ... static void Fight(ref Player player, ref Monster monster) { while (true) { // player๊ฐ monster ๊ณต๊ฒฉ monster.hp -= player.attack; if (monster.hp <= 0) { Console.WriteLine("์น๋ฆฌํ์ต๋๋ค!"); Console.WriteLine($"๋จ์ ์ฒด๋ ฅ : {player.hp}"); break; } // monster์ ๋ฐ๊ฒฉ player.hp -= monster.attack; if (player.hp <= 0) { Console.WriteLine("ํจ๋ฐฐํ์ต๋๋ค!"); break; } } } static void EnterField(ref Player player) { while (true) { Console.WriteLine("ํ๋์ ์ ์ํ์ต๋๋ค!"); // ๋๋ค์ผ๋ก 1~3 ๋ชฌ์คํฐ ์ค ํ๋๋ฅผ ์คํฐ Monster monster; CreateRandomMonster(out monster); Console.WriteLine("[1] ์ ํฌ ๋ชจ๋๋ก ๋์ "); Console.WriteLine("[2] ์ผ์ ํ๋ฅ ๋ก ๋ง์๋ก ๋๋ง"); string input = Console.ReadLine(); if (input == "1") Fight(ref player, ref monster); else if (input == "2") { // ๋๋ง์น ํ๋ฅ ์ด 33% Random rand = new Random(); int randValue = rand.Next(0, 101); if (randValue <= 33) { Console.WriteLine("๋๋ง์น๋๋ฐ ์ฑ๊ณตํ์ต๋๋ค!"); } else Fight(ref player, ref monster); } } } static void EnterGame(ref Player player) { while (true) { Console.WriteLine("๋ง์์ ์ ์ํ์ต๋๋ค!"); Console.WriteLine("[1] ํ๋๋ก ๊ฐ๋ค"); Console.WriteLine("[2] ๋ก๋น๋ก ๋์๊ฐ๊ธฐ"); string input = Console.ReadLine(); if (input == "1") EnterField(ref player); else if (input == "2") break; } } static void Main(string[] args) { while (true) { ClassType choice = ChooseClass(); if (choice == ClassType.None) continue; // ์บ๋ฆญํฐ ์์ฑ Player player; CreatePlayer(choice, out player); // ๊ฒ์ ์ ์ฅ EnterGame(ref player); } } } }โ
[ ์น์
4. ๊ฐ์ฒด์งํฅ ์ฌํ ]
# ๊ฐ์ฒด์งํฅ์ ์์
- ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ (Object Oriented Programming) ์ OOP ๋ผ๊ณ ํ๋ค.
- Object (๊ฐ์ฒด) : Obejct๋ ์ค๊ณ๋์ ํด๋นํ๋ Class๋ฅผ ํตํด ์์ฑ๋ ์ค์ฒดํ๋ ๊ฒ์ด๋ค. (์ฌ๋, ์ฌ๋ฌผ ๋ฑ)
- Class (ํด๋์ค) : Class๋ Object๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ค๊ณ๋์ ๊ฐ๋ค.
~> ํด๋น ๊ฐ์ฒด๊ฐ ์ด๋ค ์์ฑ๊ณผ ๊ธฐ๋ฅ์ ๊ฐ์ง๋์ง ์ ์ํ๋ ์ญํ ์ ํ๋ค.
- Instance (์ธ์คํด์ค) : Instance๋ Class๋ฅผ ํตํด Obejct๋ฅผ ์์ฑํ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๊ฐ๋ค.
~> Class๋ฅผ ํตํด Object๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ธ์คํด์คํ ํ๋ค๊ณ ํ๋ค.
Class๋ฅผ ํตํด Object๋ฅผ ์ธ์คํด์คํ ํ๊ธฐ ์ํ ์์ namespace CSharpStudy { class Knight { public int hp; public int attack; public void Move() { Console.WriteLine("Knight Move"); } public void Attack() { Console.WriteLine("Knight Attack"); } } class Program { static void Main(string[] args) { Knight knight = new Knight(); knight.hp = 100; knight.attack = 10; knight.Move(); knight.Attack(); } } }โ
# ๋ณต์ฌ(๊ฐ)์ ์ฐธ์กฐ
Class์ Struct์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ namespace CSharpStudy { class Knight { public int hp; public int attack; } struct Mage { public int hp; public int attack; } class Program { static void KillKnight(Knight night) { night.hp = 0; } static void KillMage(Mage mage) { mage.hp = 0; } static void Main(string[] args) { // struct๋ ๋ณต์ฌ Mage mage; // struct๋ = new Mage() ์๋ต์ด ๊ฐ๋ฅ mage.hp = 100; mage.attack = 50; KillMage(mage); // ํจ์ ๊ฒฐ๊ณผ๋ก mage์ hp๋ ๊ทธ๋๋ก 100 Mage mage2 = mage; mage2.hp = 0; // ํจ์ ๊ฒฐ๊ณผ๋ก mage์ hp๋ ๊ทธ๋๋ก 100 // class๋ ์ฐธ์กฐ Knight knight = new Knight(); knight.hp = 100; knight.attack = 10; KillKnight(knight); // ํจ์ ๊ฒฐ๊ณผ๋ก knight์ hp๋ 0 Knight knight2 = knight; knight2.hp = 100; // ํจ์ ๊ฒฐ๊ณผ๋ก knight์ hp๋ 100 } } }โ
์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ์ ์ฐจ์ดnamespace CSharpStudy { class Knight { public int hp; public int attack; public Knight Clone() { Knight knight = new Knight(); knight.hp = hp; knight.attack = attack; return knight; } } class Program { static void KillKnight(Knight night) { night.hp = 0; } static void Main(string[] args) { // ์์ ๋ณต์ฌ Knight knight = new Knight(); knight.hp = 100; knight.attack = 10; Knight knight2 = knight; knight2.hp = 0; // ํจ์ ๊ฒฐ๊ณผ๋ก knight์ hp๋ 0 // ๊น์ ๋ณต์ฌ Knight knight3 = knight.Clone(); knight2.hp = 100; // ํจ์ ๊ฒฐ๊ณผ๋ก knight์ hp๋ ๊ทธ๋๋ก 0 } } }โ
# ์คํ๊ณผ ํ
- Stack๊ณผ Heap์ ๋ฐ์ดํฐ๋ฅผ ์ํ Memory ๋ผ๋ ๊ณตํต์ ์ ๊ฐ์ง์ง๋ง, ์ฉ๋์ ๋ฐ๋ผ ๊ตฌ๋ถ๋๋ค.
- Stack์ ๋ฉ์๋์ ์คํ, ํด๋น ๋ฉ์๋๋ก ์ ๋ฌ๋๋ ๋งค๊ฐ๋ณ์, ๋ฉ์๋ ๋ด์์ ์ฌ์ฉ๋๋ ์ง์ญ๋ณ์๋ฅผ ์ฒ๋ฆฌํ๋ค.
~> Stack์ ๋ถ์์ ํ๊ณ ์ผ์์ ์ผ๋ก ์ฌ์ฉํ๋ Memory๋ก ๋ฉ๋ชจ์ฅ๊ณผ ๊ฐ์ ์กด์ฌ๋ค.
~> Stack ์์ญ์ ์ด๋ฆ์์ ์ ์ ์๋ฏ ์๋ฃ๊ตฌ์กฐ์์ ๋ค๋ฃจ๋ Stack๊ณผ ๋์๋ฐฉ์์ด ๊ฐ๋ค. (LIFO)
~> Stack ์์ญ์ ๋ฉ์๋์ ์คํ์ด ๋๋ ๊ฒฝ์ฐ ํด๋น ๋ฉ์๋์ ๊ด๋ จ๋ ์์ญ์ ํด์ ๋๋ค.
~> new ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด ์์ฑ์ ์ค์ ๋ฐ์ดํฐ ์์ฒด๋ Heap ์์ญ์, ๋ฐ์ดํฐ ์ฃผ์๋ Stack ์์ญ์ ์ ์ฅ๋๋ค.
~> Stack ์์ญ์ ๊ฐ ํ์์ด๋ค.
- Heap์ ๋์ ์ผ๋ก ํ ๋น๋๋ ๋ฐ์ดํฐ์ ๊ฐ์ฒด๋ค์ ์ฒ๋ฆฌํ๋ค. (์ฃผ๋ก Class)
~> Heap ์์ญ์ new ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฑฐ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋์ ์ผ๋ก ํ ๋น์ ์ฌ์ฉ๋๋ค.
~> C#์ C++๊ณผ ๋ฌ๋ฆฌ GC๊ฐ Heap ์์ญ์ ๊ด๋ฆฌํ์ฌ Memory ๋์ ๋ฐ ๊ธฐํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ค.
(C++์ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ง์ delete๋ฅผ ํตํด ํด์ ๋ฅผ ํด์ผ์ง๋ง Memory ๋์ ๋ฐ ๊ธฐํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์ง ๊ฐ๋ฅ)
~> Heap ์์ญ์ ์ฐธ์กฐ ํ์์ด๋ค.
# ์์ฑ์
- ์์ฑ์๋ ๋ฐํ ํ์์ ์ ์ธํ์ง ์๋๋ค.
- this() ์์ฑ์๋ ์์ฑ์์์ ๋ณธ์ธ์ ๋ค๋ฅธ ์์ฑ์๋ฅผ ํธ์ถํ๋ค.
- ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ์์ฑ์, ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ฃผ์ง ์๋ ์ด์ ๊ธฐ๋ณธ ์์ฑ์๋ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
์์ฑ์ ์์ฉ ๋ฐ this() ์์ฑ์ ์์ฉnamespace CSharpStudy { class Knight { public int hp; public int attack; public int defense; public Knight() { hp = 100; attack = 10; defense = 10; } public Knight(int hp) { this.hp = hp; } public Knight(int hp, int attack) : this(hp) { this.attack = attack; } public Knight(int hp, int attack, int defense) : this(hp, attack) { this.defense = defense; } } class Program { static void Main(string[] args) { Knight knight = new Knight(); } } }
# static์ ์ ์ฒด
- Class ๋ด๋ถ์ ํ๋ ๊ฐ์ ๊ฐ Instance ๋ง๋ค ์ ๊ฐ๊ฐ์ผ ์ ์๋ค. (์ฆ, ์ธ์คํด์ค๋ง๋ค ๊ณ ์ ํ ๊ฐ์ ๊ฐ์ง ์ ์๋ค.)
~> Class๋ฅผ ํตํด Instance๊ฐ ์์ฑ๋ ๋ ๊ฐ ๊ฐ์ฒด๋ง๋ค ๋ฐ๋ก ์๊ธด๋ค.
- Class ๋ด๋ถ์ static๊ณผ ํจ๊ป ์ ์ธํ ํ๋์ ๋ฉ์๋๋ ๊ฐ Instance์ ์ข ์๋๋ ๊ฒ์ด ์๋ ํด๋น Class์ ์ข ์๋๋ค.
~> ํด๋น Class๊ฐ ์ฒ์ ์ฌ์ฉ๋ ๋ ํ๋ฒ ์ด๊ธฐํ ๋๋ฉฐ, ๊ทธ ๋ค๋ก๋ ๊ณ์ํด์ ๋์ผํ Memory๋ฅผ ์ฌ์ฉํ๋ค.
~> Class ๋ด๋ถ์ static๊ณผ ํจ๊ป ์ ์ธํ ํ๋์ ๋ฉ์๋ ์ฌ์ฉ์ Class์ด๋ฆ.ํ๋/๋ฉ์๋์ด๋ฆ ๊ณผ ๊ฐ์ด ์ ๊ทผํด์ผํ๋ค.
~> static์ ํตํด Class๋ก ๋ถํฐ Instance๋ฅผ ์์ฑํ์ง ์๊ณ ํ๋์ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ค.
- Class ๋ด๋ถ์ static๊ณผ ํจ๊ป ์ ์ธํ ๋ฉ์๋ ๋ด๋ถ์์๋ static ํ๋๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. (Class์ Instance ํ๋ ์ฐธ์กฐ ๋ถ๊ฐ๋ฅ)
~> ๋ค๋ง ๋ด๋ถ์์ ์๋ก์ด ๊ฐ์ฒด ์์ฑ์ ํด๋น ๊ฐ์ฒด์ ํ๋ ์ฐธ์กฐ๋ ๊ฐ๋ฅํ๋ค.
- static๊ณผ ํจ๊ป ์ ์ธํ Class๋ ๋ชจ๋ ๋ฉค๋ฒ๊ฐ static ํ๋, static ๋ฉ์๋๋ก ์ด๋ฃจ์ด์ ธ ์์ผ๋ฉฐ, ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค.
static ์์ฉnamespace CSharpStudy { class Knight { // ์ ์ ํ๋ static public int counter = 1; public int id; public int hp; public int attack; // ์ ์ ๋ฉ์๋ static public void AddCounter() { counter++; } // ์ ์ ๋ฉ์๋ (static์ด๋ผ๊ณ ํด์ Instance์ ์ ๊ทผ์ ๋ชปํ๋ ๊ฒ์ X) static public Knight CreateKnight() { Knight knight = new Knight(); // ๋ค๋ง ๋ด๋ถ์์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํ๋ค. knight.hp = 100; knight.attack = 5; return knight; } public Knight() { id = counter++; hp = 100; attack = 10; } } class Program { static void Main(string[] args) { Knight knight = Knight.CreateKnight(); } } }โ
# ์์์ฑ
- ์์์ฑ์ OOP ํน์ง ์ค ํ๋์ด๋ค.
- ๋ถ๋ชจ Class (๊ธฐ๋ฐ Class) ๋ก๋ถํฐ ์์ํ์ฌ ์๋ก์ด ์์ Class (ํ์ Class)๋ฅผ ๋ง๋ค ์ ์๋ค.
- ์์์ ํตํด ๋ถ๋ชจ Class์ ํ๋ ๋ฐ ๋ฉ์๋๋ค์ ์์ Class์์ ์ฌ์ฉํ ์ ์๋ค.
์์ ์์ฉnamespace CSharpStudy { class Player // ๋ถ๋ชจ Class ๋๋ ๊ธฐ๋ฐ Class { static public int counter = 1; public int id; public int hp; public int attack; public void Move() { Console.WriteLine("Player Move!"); } public void Attack() { Console.WriteLine("Player Attack!"); } } class Knight : Player // ์์ Class ๋๋ ํ์ Class { public void Stun() { Console.WriteLine("Stun!"); } } class Program { static void Main(string[] args) { Knight knight = new Knight(); knight.Move(); knight.Attack(); } } }โ
์์์ ์์ฑ์ ์์ฉ #1 (์์ํด๋์ค๊ฐ ์์ฑ๋ ๋ ๋ถ๋ชจ Class์ ์์ฑ์๊ฐ ๋จผ์ ํธ์ถ)namespace CSharpStudy { class Player // ๋ถ๋ชจ Class ๋๋ ๊ธฐ๋ฐ Class { static public int counter = 1; public int id; public int hp; public int attack; public Player() { Console.WriteLine("Player ์์ฑ์ ํธ์ถ!"); } } class Knight : Player // ์์ Class ๋๋ ํ์ Class { public Knight() { Console.WriteLine("Knight ์์ฑ์ ํธ์ถ!"); } static public Knight CreateKnight() { Knight knight = new Knight(); knight.hp = 100; knight.attack = 5; return knight; } } class Program { static void Main(string[] args) { Knight knight = Knight.CreateKnight(); } } }โ
์์์ ์์ฑ์ ์์ฉ #2 (๋ถ๋ชจ์ ์์ฑ์๊ฐ ์ฌ๋ฌ๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ๋ถ๋ชจ์ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ํธ์ถ)namespace CSharpStudy { class Player // ๋ถ๋ชจ Class ๋๋ ๊ธฐ๋ฐ Class { static public int counter = 1; public int id; public int hp; public int attack; public Player() { Console.WriteLine("Player ์์ฑ์ ํธ์ถ!"); } public Player(int hp) { this.hp = hp; Console.WriteLine("Player hp ์์ฑ์ ํธ์ถ!"); } } class Knight : Player // ์์ Class ๋๋ ํ์ Class { public Knight() { Console.WriteLine("Knight ์์ฑ์ ํธ์ถ!"); } static public Knight CreateKnight() { Knight knight = new Knight(); knight.hp = 100; knight.attack = 5; return knight; } } class Program { static void Main(string[] args) { Knight knight = Knight.CreateKnight(); } } }โ
์์์ ์์ฑ์ ์์ฉ #3 ๋ฐ base() ์์ฑ์ ์์ฉnamespace CSharpStudy { class Player // ๋ถ๋ชจ Class ๋๋ ๊ธฐ๋ฐ Class { static public int counter = 1; public int id; public int hp; public int attack; public Player() { Console.WriteLine("Player ์์ฑ์ ํธ์ถ!"); } public Player(int hp) { this.hp = hp; Console.WriteLine("Player hp ์์ฑ์ ํธ์ถ!"); } } class Knight : Player // ์์ Class ๋๋ ํ์ Class { public Knight() : base(100) { Console.WriteLine("Knight ์์ฑ์ ํธ์ถ!"); } static public Knight CreateKnight() { Knight knight = new Knight(); knight.hp = 100; knight.attack = 5; return knight; } } class Program { static void Main(string[] args) { Knight knight = Knight.CreateKnight(); } } }โ
# ์๋์ฑ
- ์๋์ฑ์ OOP ํน์ง ์ค ํ๋์ด๋ค.
- ์ฌ์ฉ์์๊ฒ ํ์ํ ์ต์์ ๊ธฐ๋ฅ๋ง์ ๋ ธ์ถํ๊ณ ๋ด๋ถ๋ฅผ ๊ฐ์ถ๋ ๊ฒ์ด๋ค.
์ ๊ทผ ์ ํ์๋ฅผ ํตํ ์๋์ฑ ์์ฉnamespace CSharpStudy { class Knight { int hp; // ์ ๊ทผ ์ ํ์๋ฅผ ์ ์ธํ์ง ์์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก private public void SetHp(int hp) { this.hp = hp; } } class Program { static void Main(string[] args) { Knight knight = new Knight(); knight.SetHp(100); } } }โ
+ ์ถ๊ฐ ๊ฒ์ ( https://usingsystem.tistory.com/6 )
- ์๋์ฑ ๊ตฌํ ๋ฐฉ๋ฒ
1. ์ ๊ทผ ์ ํ์
2. ํ๋กํผํฐ
3. ๋ ์ฝ๋
4. ๋ฌด๋ช ํ์
# ํด๋์ค ํ์ ๋ณํ
- ์์ ํด๋์ค ~> ๋ถ๋ชจ ํด๋์ค ๋ณํ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
- ๋ถ๋ชจ ํด๋์ค ~> ์์ ํด๋์ค ๋ณํ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
~> ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง๋ ํ๋ก๊ทธ๋จ์ ์คํํด๋ด์ผ๋ง ํ์ธ์ด ๊ฐ๋ฅํ๋ค.
~> ์ด๋ฅผ is ์ฐ์ฐ์์ as ์ฐ์ฐ์๋ฅผ ํตํด ํด๊ฒฐํ ์ ์๋ค.
ํด๋์ค ํ์ ๋ณํ ์์ (์คํ ๊ฒฐ๊ณผ๋ ์ค๋ฅ ๋ฐ์)namespace CSharpStudy { class Player { protected int hp; protected int attack; } class Knight : Player { } class Mage : Player { public int mp; } class Program { static void Main(string[] args) { Knight knight = new Knight(); Mage mage = new Mage(); // ์์ ํด๋์ค -> ๋ถ๋ชจ ํด๋์ค ๋ณํ์ ๋ฌธ์ X Player player = knight; // ๋ถ๋ชจ ํด๋์ค -> ์์ ํด๋์ค ๋ณํ์ ๋ฌธ์ ๋ฐ์ Mage otherMage = (Mage)player; // ํ๋ก๊ทธ๋จ์ ์คํํด๋ด์ผ ์ค๋ฅ ๋ฐ๊ฒฌ ๊ฐ๋ฅ } } }โ
is ์ฐ์ฐ์๋ฅผ ํตํ ํด๋์ค ํ์ ๋ณํ ์์ ์ค๋ฅ ์์ namespace CSharpStudy { class Player { protected int hp; protected int attack; } class Knight : Player { } class Mage : Player { public int mp; } class Program { static void EnterGame(Player player) { // is ๋ฌธ๋ฒ์ ํตํ ์ค๋ฅ ์์ bool isMage = player is Mage; if (isMage) { Mage mage = (Mage)player; mage.mp = 10; } } static void Main(string[] args) { Knight knight = new Knight(); Mage mage = new Mage(); EnterGame(knight); } } }โ
as ์ฐ์ฐ์๋ฅผ ํตํ ํด๋์ค ํ์ ๋ณํ ์์ ์ค๋ฅ ์์ namespace CSharpStudy { class Player { protected int hp; protected int attack; } class Knight : Player { } class Mage : Player { public int mp; } class Program { static void EnterGame(Player player) { // as ๋ฌธ๋ฒ์ ํตํ ์ค๋ฅ ์์ Mage mage = player as Mage; if (mage != null) { mage.mp = 10; } } static void Main(string[] args) { Knight knight = new Knight(); Mage mage = new Mage(); EnterGame(knight); } } }โ
+ ์ถ๊ฐ ๊ฒ์ ( https://dybz.tistory.com/94 )
- is ์ฐ์ฐ์
~> Casting ๊ฐ๋ฅ ์ฌ๋ถ๋ง์ ํ๋จํ๋ค.
~> Casting์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ true๋ฅผ, ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ false๋ฅผ returnํ๋ค.
- as ์ฐ์ฐ์
~> Casting์ ์ฌ์ฉํ๋ค.
~> Casting์ ์ฑ๊ณตํ ๊ฒฝ์ฐ Casting ๊ฒฐ๊ณผ๋ฅผ, ์คํจํ ๊ฒฝ์ฐ null์ returnํ๋ค.
# ๋คํ์ฑ
- ๋คํ์ฑ์ OOP ํน์ง ์ค ํ๋์ด๋ค.
- ๋คํ์ฑ์ Object๊ฐ ์ฌ๋ฌ ํํ๋ฅผ ๊ฐ์ง ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
- virtual Keyword๋ ์์ Class์์ ์ฌ์ ์ (override) ๋ฅผ ํ ์ ์๋๋ก ๋ง๋ค์ด์ค๋ค.
- override Keyword๋ ๋ถ๋ชจ Class์์ virtual์ด๋ abstract๋ก ์ ์ธ๋ ๋ฉ์๋๋ ํ๋กํผํฐ๋ฅผ ์ฌ์ ์ (override) ํ๋ค.
virtual Keyword์ override Keyword ์์ฉusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Player { protected int hp; protected int attack; public virtual void Move() { Console.WriteLine("Player ์ด๋!"); } } class Knight : Player { public override void Move() { base.Move(); // ๋ถ๋ชจ Class๊ฐ ๊ฐ์ง Move() ๋ฉ์๋๋ฅผ ์คํ Console.WriteLine("Knight ์ด๋!"); } } class Program { static void EnterGame(Player player) { player.Move(); // ๋งค๊ฐ๋ณ์์ Type์ Player์ง๋ง override๋ฅผ ํตํด knight์ Move() ๋ฉ์๋๊ฐ ์คํ } static void Main(string[] args) { Knight knight = new Knight(); EnterGame(knight); } } }โ
+ ์ถ๊ฐ ๊ฒ์ ( https://kimasill.tistory.com/entry/C-Abstract%EC%B6%94%EC%83%81Virtual%EA%B0%80%EC%83%81Interface%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%B0%A8%EC%9D%B4 )
- virtual๊ณผ abstract์ ์ฐจ์ด์
~> virtual Keyword ์ฌ์ฉ์ ์์ Class์์ ํ์์ ๋ฐ๋ผ ์ฌ์ ์ (override) ํ ์ ์์ง๋ง ํ์๋ ์๋๋ค.
~> virtual Keyword ์ฌ์ฉ์ ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
~> abstract Keyword ์ฌ์ฉ์ abstract Class๋ ์์ฒด์ ์ผ๋ก ๊ตฌํ์ด ๋ถ๊ฐ๋ฅํ๊ณ , ์์ Class์์ ๋ฐ๋์ ๊ตฌํํด์ผ ํ๋ค.
~> abstract Keyword ์ฌ์ฉ์ Class ๋ํ abstract์ผ๋ก ์ ์ธํ๋ค.
~> abstract Keyword ์ฌ์ฉ์ ๊ฐ์ฒด ์์ฑ์ด ๋ถ๊ฐ๋ฅํ๋ค. (abstract class ๋ฅผ ์์๋ฐ์ class๋ ๊ฐ์ฒด ์์ฑ ๊ฐ๋ฅ)
+ ์ถ๊ฐ ๊ฒ์ ( https://ssabi.tistory.com/49 )
- overloading๊ณผ overriding์ ์ฐจ์ด
~> overloading์ ์ฌ์ ์ ์๋ฏธ๋ "๊ณผ์ ํ๋ค" ์ด๋ค.
~> overloading์ ํ๋์ ๋ฉ์๋์ ์ฌ๋ฌ๊ฐ์ ๊ตฌํ์ ๊ณผ์ ํ ์ ์๋ค.
~> overriding์ ์ฌ์ ์ ์๋ฏธ๋ "๋ ์ค์ํ", "์ต์ฐ์ ์ ๋๋" ์ด๋ค.
~> overriding์ ๋ถ๋ชจ Class์์ ๋ฌผ๋ ค๋ฐ์ ๋ฉ์๋๋ฅผ ์์ Class์์ ์ฌ์ ์ํ์ฌ ์์ ํด๋์ค์ ๋ฉ์๋๊ฐ ๋ ์ฐ์ ์ ๋๋ค.
# ๋ฌธ์์ด ๋๋ฌ๋ณด๊ธฐ
string ๊ด๋ จ ๋ฉ์๋๋คusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { static void Main(string[] args) { string name = "Harry Potter"; // 1. ์ฐพ๊ธฐ bool found = name.Contains("Harry"); int index = name.IndexOf('P'); // ์ฐพ์ง ๋ชปํ ๊ฒฝ์ฐ -1 ์ return // 2. ๋ณํ name = name + " Junior"; string lowerCaseName = name.ToLower(); string upperCaseName = name.ToUpper(); string newName = name.Replace('r', 'l'); // 3. ๋ถํ string[] names = name.Split(new char[] { ' ' }); string substringName = name.Substring(5); } } }โ
[ ์น์ 5. TextRPG2 ]
# TextRPG2 ํ๋ ์ด์ด & ๋ชฌ์คํฐ ์์ฑ
TextRPG2์์ ๋ชจ๋ ์๋ช ์ฒด๋ฅผ ์ํ ๋ถ๋ชจ Class Creature ์์ฑusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpStudy { public enum CreatureType { None, Player = 1, Monster = 2 } class Creature { CreatureType type; protected int hp = 0; protected int attack = 0; protected Creature(CreatureType type) { this.type = type; } public void SetInfo(int hp, int attack) { this.hp = hp; this.attack = attack; } public int GetHp() { return hp; } public int GetAttack() { return attack; } public bool IsDead() { return hp <= 0; } public void OnDamaged(int damage) { hp -= damage; if (hp < 0) hp = 0; } } }โ
Creature๋ฅผ ์์๋ฐ๋ Player ์์ฑusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpStudy { public enum PlayerType { None = 0, Knight = 1, Archer = 2, Mage = 3 } class Player : Creature { protected PlayerType type = PlayerType.None; // ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ์์ฑ์, ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ฃผ์ง ์๋ ์ด์ ๊ธฐ๋ณธ ์์ฑ์๋ ์ฌ์ฉ ๋ถ๊ฐ protected Player(PlayerType type) : base(CreatureType.Player) { this.type = type; } public PlayerType GetPlayerType() { return type; } } class Knight : Player { public Knight() : base(PlayerType.Knight) { SetInfo(100, 10); } } class Archer : Player { public Archer() : base(PlayerType.Archer) { SetInfo(75, 12); } } class Mage : Player { public Mage() : base(PlayerType.Mage) { SetInfo(50, 15); } } }โ
Creature๋ฅผ ์์ ๋ฐ๋ Monster ์์ฑusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpStudy { public enum MonsterType { None = 0, Slime = 1, Orc = 2, Skeleton = 3 } class Monster : Creature { protected MonsterType type; protected Monster(MonsterType type) : base(CreatureType.Monster) { this.type = type; } public MonsterType GetMonsterType() { return type; } } class Slime : Monster { public Slime() : base(MonsterType.Slime) { SetInfo(10, 1); } } class Orc : Monster { public Orc() : base(MonsterType.Orc) { SetInfo(20, 2); } } class Skeleton : Monster { public Skeleton() : base(MonsterType.Skeleton) { SetInfo(15, 5); } } }โ
TextRPG2 ํ๋ ์ด์ด & ๋ชฌ์คํฐ ์์ฑusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { static void Main(string[] args) { Player player = new Knight(); Monster monster = new Orc(); int damage = player.GetAttack(); monster.OnDamaged(damage); } } }โ
# TextRPG2 ๊ฒ์ ์งํ & ๋ง๋ฌด๋ฆฌ
TextRPG2 ๊ฒ์ ์งํ์ ์ํ Game ์์ฑusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpStudy { public enum GameMode { None, Lobby, Town, Field } // ๊ฒ์ ์งํ๊ณผ ๊ด๋ จ๋ ์ ๋ฐ์ ์ธ ์ฌํญ๋ค์ ๊ด๋ฆฌ class Game { private GameMode mode = GameMode.Lobby; private Player player = null; private Monster monster = null; Random rand = new Random(); public void Process() { switch (mode) { case GameMode.Lobby: ProcessLobby(); break; case GameMode.Town: ProcessTown(); break; case GameMode.Field: ProcessField(); break; } } private void ProcessLobby() { Console.WriteLine("์ง์ ์ ์ ํํ์ธ์"); Console.WriteLine("[1] ๊ธฐ์ฌ"); Console.WriteLine("[2] ๊ถ์"); Console.WriteLine("[3] ๋ฒ์ฌ"); string input = Console.ReadLine(); switch (input) { case "1": player = new Knight(); mode = GameMode.Town; break; case "2": player = new Archer(); mode = GameMode.Town; break; case "3": player = new Mage(); mode = GameMode.Town; break; } } private void ProcessTown() { Console.WriteLine("๋ง์์ ์ ์ฅํ์ต๋๋ค!"); Console.WriteLine("[1] ํ๋๋ก ๊ฐ๊ธฐ"); Console.WriteLine("[2] ๋ก๋น๋ก ๋์๊ฐ๊ธฐ"); string input = Console.ReadLine(); switch (input) { case "1": mode = GameMode.Field; break; case "2": mode = GameMode.Lobby; break; } } private void ProcessField() { Console.WriteLine("ํ๋์ ์ ์ฅํ์ต๋๋ค!"); Console.WriteLine("[1] ์ธ์ฐ๊ธฐ"); Console.WriteLine("[2] ์ผ์ ํ๋ฅ ๋ก ๋ง์ ๋์๊ฐ๊ธฐ"); CreateRandomMonster(); string input = Console.ReadLine(); switch (input) { case "1": ProcessFight(); break; case "2": TryEscape(); break; } } private void CreateRandomMonster() { int randValue = rand.Next(0, 3); switch (randValue) { case 0: monster = new Slime(); Console.WriteLine("์ฌ๋ผ์์ด ์์ฑ๋์์ต๋๋ค!"); break; case 1: monster = new Orc(); Console.WriteLine("์คํฌ๊ฐ ์์ฑ๋์์ต๋๋ค!"); break; case 2: monster = new Skeleton(); Console.WriteLine("์ค์ผ๋ ํค์ด ์์ฑ๋์์ต๋๋ค!"); break; } } private void ProcessFight() { while (true) { int damage = player.GetAttack(); monster.OnDamaged(damage); if (monster.IsDead()) { Console.WriteLine("์น๋ฆฌํ์ต๋๋ค"); Console.WriteLine($"๋จ์ ์ฒด๋ ฅ : {player.GetHp()}"); break; } damage = monster.GetAttack(); player.OnDamaged(damage); if (player.IsDead()) { Console.WriteLine("ํจ๋ฐฐํ์ต๋๋ค"); mode = GameMode.Lobby; break; } } } private void TryEscape() { int randValue = rand.Next(0, 101); if (randValue < 33) { mode = GameMode.Town; } else { ProcessFight(); } } } }
TextRPG2 ๊ฒ์ ์งํusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { static void Main(string[] args) { Game game = new Game(); while (true) { game.Process(); } } } }
[ ์น์ 6. ์๋ฃ๊ตฌ์กฐ ๋ง๋ณด๊ธฐ ]
# ๋ฐฐ์ด
- ๋ฐฐ์ด์ ์ฐธ์กฐ ํ์ ์ด๋ค.
- foreach๋ฌธ์ ๋ฐฐ์ด, Collection ์์ ์ผ๋ จ์ ๋ฐ์ดํฐ๋ค์ ์ฐจ๋ก๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๋ฐ๋ณต๋ฌธ์ด๋ค.
๋ฐฐ์ด ๋ฐ foreach๋ฌธ ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { // ๋ฐฐ์ด (์ฐธ์กฐ ํ์ ) int[] MathScores = new int[] { 10, 20, 30, 40, 50 }; int[] EngScores = { 40, 50, 70, 90 }; for (int i = 0; i < MathScores.Length; i++) { Console.WriteLine("MathScore : " + MathScores[i]); } foreach (int score in EngScores) { Console.WriteLine($"EngScore : {score}"); } } } }โ
# ๋ค์ฐจ์ ๋ฐฐ์ด
๋ค์ฐจ์ ๋ฐฐ์ด ์์ฉ #1namespace CSharpStudy { class Program { static void Main(string[] args) { int[ , ] Array_1 = new int[ , ] { { 1, 2, 3 }, { 4, 5, 6 } }; int[ , ] Array_2 = { { 1, 2, 3 }, { 4, 5, 6 } }; } } }โ
๋ค์ฐจ์ ๋ฐฐ์ด ์์ฉ #2namespace CSharpStudy { class Map { int[,] tiles = { { 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 1 }, { 1, 0, 0, 0, 1 }, { 1, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1 } }; public void Render() { ConsoleColor defaultColor = Console.ForegroundColor; for (int y = 0; y < tiles.GetLength(0); y++) { for (int x = 0; x < tiles.GetLength(1); x++) { if (tiles[y, x] == 1) Console.ForegroundColor = ConsoleColor.Red; else Console.ForegroundColor = ConsoleColor.Green; Console.Write("\u25cf"); } Console.WriteLine(); } Console.ForegroundColor = defaultColor; } } class Program { static void Main(string[] args) { Map map = new Map(); map.Render(); } } }
๊ฐ๋ณ ๋ฐฐ์ด ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { int[][] a = new int[3][]; a[0] = new int[3]; a[1] = new int[6]; a[2] = new int[2]; a[0][0] = 1; } } }โ
# List
- List๋ ์ฐธ์กฐ ํ์ ์ด๋ค.
- List๋ ๋ฐฐ์ด๊ณผ ๋ฌ๋ฆฌ ๋์ ์ผ๋ก ํฌ๊ธฐ ์กฐ์ ์ด ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ๋ฐฐ์ด์ ํฌ๊ธฐ์ ๋ํด ํฌ๊ฒ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค.
~> ๋ฐฐ์ด๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ฌ ์์์ ์ ๊ทผํ ์ ์๋ค. (List๊ฐ ์ต์ 1๊ฐ ์ด์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ผ ์ ๊ทผ ๊ฐ๋ฅ)
List ์์ฉnamespace CSharpStudy { class Program { static void Main(string[] args) { List<int> list = new List<int>(); for (int i = 0; i < 5; i++) list.Add(i); // list์ ๋งจ ๋ค์ ๋ฐ์ดํฐ ์ถ๊ฐ list.Insert(2, 999); // index๋ฅผ ํตํ ๋ฐ์ดํฐ ์ฝ์ list.Remove(3); // ๊ฐ์ ํตํ ๋ฐ์ดํฐ ์ญ์ (์ฌ๋ฌ๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ๊ฐ์ฅ ์ฒ์์ผ๋ก ๋ฐ๊ฒฌํ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ) list.RemoveAt(0); // index๋ฅผ ํตํ ๋ฐ์ดํฐ ์ญ์ list.Clear(); // list๋ฅผ ์ด๊ธฐํ for (int i = 0; i < list.Count; i++) // list์ ํฌ๊ธฐ๋ Length๋ฅผ ์ฌ์ฉํ๋ ๋ฐฐ์ด๊ณผ ๋ฌ๋ฆฌ Count ์ฌ์ฉ Console.WriteLine(list[i]); foreach (int num in list) Console.WriteLine(num); } } }โ
# Dictionary
- Dictionary๋ ์ฐธ์กฐ ํ์ ์ด๋ค.
- Dictionary๋ ์ธ๋ฑ์ค ๋์ Key ๊ฐ์ ํตํด Value ๊ฐ์ ์ฐพ๋๋ค.
- Hash Table์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋น ๋ฅด์ง๋ง, ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์ฌํ๋ค.
Dictionary ์์ฉnamespace CSharpStudy { class Monster { public int id; public Monster(int id) { this.id = id; } } class Program { static void Main(string[] args) { Dictionary<int, Monster> dic = new Dictionary<int, Monster>(); for (int i = 0; i < 10000; i++) { dic.Add(i, new Monster(i)); } Monster monster; bool isFound = dic.TryGetValue(5000, out monster); dic.Remove(7777); dic.Clear(); } } }โ
+ ์ถ๊ฐ ๊ฒ์ ( https://coding-shop.tistory.com/53 )
- ContainsKey() ์ TryGetValue() ์ฐจ์ด์
~> ContainsKey() ์ TryGetValue() ๋ Dictionary์ Key ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ๋จํ๊ณ bool Type์ return ํ๋ค.
~> ContainsKey() ๋ Key์ ์ฐ๊ฒฐ๋ Value ๊ฐ์ ์ถ๋ ฅํ์ง ์๋๋ค.
~> TryGetValue() ๋ Key์ ์ฐ๊ฒฐ๋ Value ๊ฐ์ ์ถ๋ ฅํ๋ค.
[ ์น์ 7. ์์๋๋ฉด ์ ์ฉํ ๊ธฐํ ๋ฌธ๋ฒ ]
# Generic (์ผ๋ฐํ)
- Generic์ ํน์ ๋ฐ์ดํฐ ํ์ ์ ๊ตญํ๋์ง ์๊ณ ๋ชจ๋ ํ์ ์ ํ์ฉํ๋ Generic Class์ ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
~> ์ด๋ ํน์ ์กฐ๊ฑด์๋ง ๋์๋๋ ๋ฐ์ดํฐ ํ์ ์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, ์ด๋ where Keyword๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฝ ์กฐ๊ฑด์
์ถ๊ฐํ ์ ์๋ค.
Generic Class ์์ฉnamespace CSharpStudy { class Program { class MyList<T> { T[] arr = new T[10]; public T GetItem(int i) { return arr[i]; } } static void Main(string[] args) { MyList<int> myIntList = new MyList<int>(); int intItem = myIntList.GetItem(0); MyList<float> myFloatList = new MyList<float>(); float floatItem = myFloatList.GetItem(0); } } }โ
Generic Function ์์ฉnamespace CSharpStudy { class Program { static void GenericFunc<T>(T input) { Console.WriteLine(input); } static void Main(string[] args) { GenericFunc<int>(3); GenericFunc<float>(5.0f); } } }โ
+ ์ถ๊ฐ ๊ฒ์ ( https://velog.io/@livelyjuseok/C-Object-%ED%83%80%EC%9E%85%EA%B3%BC-%EB%B0%95%EC%8B%B1-%EC%96%B8%EB%B0%95%EC%8B%B1 )
- Object ํ์ ์ ๋ชจ๋ ํ์ (int, float ...) ๋ถํฐ ์ฐธ์กฐ (Class, string ...) ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ ๋ง๋ค์ด๋ด๋ ๋ชจ๋ ๋ฐ์ดํฐ Type๋ค๊น์ง๋
๊ฐ์ฒด๋ฅผ ๋ด์ ์ ์๋ค.
~> ์ด๋ฌํ ์ด์ ๋ C#์์๋ ๋ชจ๋ ๋ฐ์ดํฐ Type์ด Object๋ฅผ ์์ ๋ฐ๋๋ก ๊ตฌ์กฐ๊ฐ ์ง์ฌ์ ธ ์๊ธฐ ๋๋ฌธ์ด๋ค.
~> ํ์ง๋ง ๋ง๊ตฌ์ก์ด๋ก ์ฌ์ฉ์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ Boxing๊ณผ UnBoxing์ ๊ฐ๋ ์ ์ดํดํด์ผ ํ๋ค.
- Boxing์ด๋ Stack ์์ญ์ ์ ์ฅ๋ ๊ฐ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ Object ํ์ ์ ํตํด Heap ์์ญ์ ์ ์ฅํ๋ ๊ณผ์ ์ ๋งํ๋ค.
~> ๋ง ๊ทธ๋๋ก ๋ฐ์ค๋ก ๊ฐ์ธ๋ ๊ณผ์ ์ด๋ฉฐ, Object์ ๊ฐ ํ์ ์ int ๊ฐ์ ๋ฃ์ผ๋ฉด Stack ์์ญ์ ์ ์ฅ๋์ด์ผ ํ๋ ๊ฐ์ด Box๋ก
๊ฐ์ธ์ ธ Heap ์์ญ์ ์ ์ฅ๋๋ค.
- UnBoxing์ ์ด๋ ๊ฒ Box๋ก ๊ฐ์ธ์ง ๋ฐ์ดํฐ๋ฅผ ํ์ด๋ด๋ ๊ณผ์ ์ ๋งํ๋ค.
- Object obj = 5 ๊ฐ Boxing์ ์์, int a = (int)obj ๊ฐ UnBoxing์ ์์์ด๋ค.
# Interface (์ธํฐํ์ด์ค)
- interface์ ํน์ง
~> C#์ ๋ค์ค ์์์ ์ง์ํ์ง ์์ง๋ง, interface๋ ๋ค์ค ์์์ด ๊ฐ๋ฅํ๋ค.
~> interface๋ ๋ฉค๋ฒ ๋ณ์๋ฅผ ํฌํจํ ์ ์๋ค.
~> interface๋ ์ ๊ทผ ์ ํ ํ์ ์๋ฅผ ์ฌ์ฉํ ์ ์๊ณ , ๊ตฌํ๋ถ๊ฐ ์กด์ฌํ์ง ์๋๋ค. (์ฆ, ์์ฒด์ ์ผ๋ก ๊ตฌํ์ด ๋ถ๊ฐ๋ฅ)
~> interface๋ฅผ ์์๋ฐ๋ Class๋ ๋ฐ๋์ interface์ ๋ชจ๋ ๋ฉ์๋๋ฅผ override (์ฌ์ ์) ํด์ผ ํ๋ค.
(override์ ๋ชจ๋ ๋ฉ์๋๋ public ์ผ๋ก ์ ์ธ)
~> interface๋ ๊ฐ์ฒด ์์ฑ์ด ๋ถ๊ฐ๋ฅํ์ง๋ง, interface๋ฅผ ์์ ๋ฐ์ Class๋ ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
+ ์ถ๊ฐ ์ ๋ฆฌ
- virtual๊ณผ abstract๊ณผ interface์ ์ฐจ์ด
virtual์ ํน์งnamespace CSharpStudy { class Monster { int hp; public virtual void Shout() { Console.WriteLine("Monster์ Shout!"); } } class Orc : Monster { public override void Shout() { Console.WriteLine("Orc์ Shout!"); } } class Skeleton : Monster { // virtual์ ๋ํ override๋ ํ์ X } class Program { static void Main(string[] args) { // virtual์ ๊ฐ์ฒด ์์ฑ ๊ฐ๋ฅ Monster monster = new Monster(); } } }โ
abstract์ ํน์งnamespace CSharpStudy { abstract class Monster { int hp; public abstract void Shout(); // ์์ฒด์ ์ผ๋ก๋ ๊ตฌํ ๋ถ๊ฐ๋ฅ } class Orc : Monster { public override void Shout() // abstract์ ๋ํ override๋ ํ์ { Console.WriteLine("Orc์ Shout!"); } } class Skeleton : Monster { public override void Shout() // abstract์ ๋ํ override๋ ํ์ { Console.WriteLine("Skeleton์ Shout!"); } } class Program { static void Main(string[] args) { // abstract์ ๊ฐ์ฒด ์์ฑ ๋ถ๊ฐ๋ฅ // Monster monster = new Monster(); } } }โ
interface์ ํน์งnamespace CSharpStudy { abstract class Monster { int hp; public abstract void Shout(); } interface IFlyable { // ๋ฉค๋ฒ ๋ณ์ ํฌํจ ๋ถ๊ฐ๋ฅ // bool isFly; void Fly(); // ์ ๊ทผ ์ ํ ํ์ ์ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ, ์์ฒด์ ์ผ๋ก๋ ๊ตฌํ ๋ถ๊ฐ๋ฅ } interface IRunable { // ๋ฉค๋ฒ ๋ณ์ ํฌํจ ๋ถ๊ฐ๋ฅ // int speed; void Run(); // ์ ๊ทผ ์ ํ ํ์ ์ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ, ์์ฒด์ ์ผ๋ก๋ ๊ตฌํ ๋ถ๊ฐ๋ฅ } class Orc : Monster { public override void Shout() { Console.WriteLine("Orc์ Shout!"); } } class Skeleton : Monster { public override void Shout() { Console.WriteLine("Skeleton์ Shout!"); } } class FlyableOrc : Orc, IFlyable, IRunable // interface๋ ๋ค์ค ์์ ๊ฐ๋ฅ { public void Fly() // ์ ๊ทผ ์ ํ ํ์ ์๋ ๋ฐ๋์ public { Console.WriteLine("Orc์ Fly!"); // interface์ ๋ํ override๋ ํ์ } public void Run() // ์ ๊ทผ ์ ํ ํ์ ์๋ ๋ฐ๋์ public { Console.WriteLine("Orc์ Run!"); // interface์ ๋ํ override๋ ํ์ } } class Program { static void Main(string[] args) { // interface๋ ๊ฐ์ฒด ์์ฑ ๋ถ๊ฐ๋ฅ // IFlyable iflyable = new IFlyable(); // interface๋ฅผ ์์ ๋ฐ์ Class์ ๊ฐ์ฒด ์์ฑ์ ๊ฐ๋ฅ FlyableOrc flyableOrc = new FlyableOrc(); } } }
+ ์ถ๊ฐ ๊ฒ์ ( https://yasic-or-nunch.tistory.com/23 )
- C#์ ๋ค์ค ์์์ ์ง์ํ์ง ์๋๋ค. ์ด๋ฌํ ์ด์ ๋ "์ฃฝ์์ ๋ค์ด์๋ชฌ๋" ๋๋ฌธ์ด๋ค.
- ์ฃฝ์์ ๋ค์ด์๋ชฌ๋๋?
~> 1๊ฐ์ ๋ถ๋ชจ Class๋ฅผ 2๊ฐ์ ์์ Class๊ฐ ์์ ๋ฐ๊ณ , 2๊ฐ์ ์์ Class๋ฅผ ๋ค์ 1๊ฐ์ ์์ Class๊ฐ ์์ ๋ฐ๋ ๊ฒ์ด๋ค.
~> ์์ ๊ทธ๋ฆผ์์ ComboDrive๊ฐ burn() ํจ์๋ฅผ ํธ์ถ์ ์ด๋ค ๋ถ๋ชจ Class์ burn() ํจ์๋ฅผ ์คํ ์ํฌ์ง ๋ชจํธํ๋ค.
# Property (ํ๋กํผํฐ)
- Property๋ OOP์ ํน์ง ์ค ํ๋์ธ ์๋์ฑ์ ์ํด ์ฌ์ฉํ๋ค.
~> Property๋ get๊ณผ set์ ํตํด private๋ก ์ ์ธ๋ ๋ณ์์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋๋ก ํ๋ค.
~> ์ ๋ณด ์๋์ ์ํด private๋ก ์ ์ธํ์์ผ๋, get๊ณผ set์ ํตํด ๋ณ์์ ์ ๊ทผํ ์ ์๋๋ผ๋ Property๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋
๋ณ์์ ๊ฐ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ๊ฐ์ ธ์ฌ ๋ ์กฐ๊ฑด์ ๊ฑธ์ด์ ๋ณ์์ ์ ๊ทผ์ ์ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
Property ์์ฉnamespace CSharpStudy { class Knight { private int hp; public int Hp { get { return hp; } set { hp = value; } // ๊ธฐ๋ณธ์ ์ผ๋ก ๋งค๊ฐ๋ณ์๋ value Keyword๊ฐ ์ ๊ณต๋๋ค. } } class Program { static void Main(string[] args) { Knight knight = new Knight(); knight.Hp = 100; int hp = knight.Hp; } } }โ
์๋ ๊ตฌํ Property ์์ฉnamespace CSharpStudy { class Knight { public int HP { get; set; } = 100 } class Program { static void Main(string[] args) { Knight knight = new Knight(); int hp = knight.HP; } } }โ
# Delegate (๋๋ฆฌ์)
- Delegate๋ ๋ฉ์๋ ์์ฒด๋ฅผ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ํ์์ด๋ค. (ํจ์๊ฐ ์๋ ํ์ (int, string ...) ์ธ ๊ฒ์ ์ ์)
~> ๋ฒํผ ํด๋ฆญ์ ๋ฐ์ํ๋ ์ผ๋ค์ ์์ฐจ์ ์ผ๋ก ์ฝ๋ฉํ ๊ฒฝ์ฐ UI์ ๊ด๋ จ๋ Logic๊ณผ ๊ฒ์๊ณผ ๊ด๋ จ๋ Logic ์ฌ์ด์
๊ฐ์ญ ๋ฐ ๋ณต์ก์ฑ์ด ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์๋ค. ๋ฐ๋ผ์ ์ต๋ํ ๋ถ๋ฆฌ๋ฅผ ์์ผ ๊ด๋ฆฌํด์ผ ์ฅ๊ธฐ์ ์ธ ์ฐจ์์์ ์ ๋ฆฌํ๋ค.
~> Unity ์์ฒด์์ ์ ๊ณตํ๋ Event ๋ฉ์๋๋ค์ ์์ฒด์ ์ผ๋ก ์์ ํ ์ ์๋ค.
~> ์์ ๊ฐ์ ๋ฌธ์ ๋ค์ ๋ฉ์๋ ์์ฒด๋ฅผ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ Delegate ๋ฅผ ํตํด ํด๊ฒฐํ ์ ์๋ค.
- Delegate ๋ชฉ๋ก์ ์คํํ ๋ฉ์๋๋ค์ ๋ฑ๋ก ํด๋๋ฉด ํด๋น Delegate๊ฐ ๋ฑ๋ก๋ ํจ์๋ค์ ์ฐ์์ ์ผ๋ก ๋์ ์คํ์์ผ์ค๋ค.
- Delegate ์ ์ธ์ ๋ฑ๋กํ ์ ์๋ ํจ์์ ์กฐ๊ฑด์ ์ ํํ๋ค. (๋งค๊ฐ๋ณ์, ๋ฐํ๊ฐ)
- Delegate๋ฅผ ์ง์ ์ ์ธํ์ง ์์๋, C#์์ ์ ๊ณตํ๋ Func, Action์ ํตํด Delegate ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
~> Anonymous Function (๋ฌด๋ช ํจ์ or ์ต๋ช ํจ์) ์ ํตํด ์์ฑํ๋ค.
~> ๋ฐํ๊ฐ์ด ์กด์ฌํ ๊ฒฝ์ฐ Func์, ๋ฐํ๊ฐ์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ Action์ ์ฌ์ฉํ๋ค.
(Func์ < > ์์ ๋ค์ด์๋ n๊ฐ์ ํ์ ์ค ๋ง์ง๋ง์ ๋ฐํ๊ฐ, ๋๋จธ์ง๋ ์ธ์์ ํด๋น)
Delegate ์์ฉusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { // delegate : ๋ฉ์๋ ์์ฒด๋ฅผ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ํ์ // ์ธ์ : X, ๋ฐํ๊ฐ : int // OnClicked : delegate ํ์์ ์ด๋ฆ delegate int OnClicked(); static void ButtonPressed (OnClicked clickedFunction) { clickedFunction(); } static int TestDelegate() { Console.WriteLine("Hello Delegate"); return 0; } static int TestDelegate2() { Console.WriteLine("Hello Delegate2"); return 0; } static void Main(string[] args) { // delegate ์ฌ์ฉ ๋ฐฉ๋ฒ #1 ButtonPressed(TestDelegate); ButtonPressed(TestDelegate2); // delegate ์ฌ์ฉ ๋ฐฉ๋ฒ #2 (๊ฐ์ฒด ์์ฑ ๋ฐฉ๋ฒ) OnClicked clicked = new OnClicked(TestDelegate); clicked += TestDelegate2; // ๊ฐ์ฒด ์์ฑ์ delegate chaining ๊ฐ๋ฅ clicked(); // delegate ์ฌ์ฉ ๋ฐฉ๋ฒ #3 OnClicked clicked2 = new OnClicked(TestDelegate); clicked2 += TestDelegate2; // ๊ฐ์ฒด ์์ฑ์ delegate chaining ๊ฐ๋ฅ ButtonPressed(clicked2); } } }โ
# Event (์ด๋ฒคํธ)
- Event๋ Observer Pattern ์ ์ฌ์ฉํ๋ค.
~> Observer Pattern ์ด๋ ํ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ฐ๋๋ฉด ํด๋น ๊ฐ์ฒด์ ์์กดํ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋คํํ ์ฐ๋ฝ์ด ๊ฐ์ ์๋์ผ๋ก ๋ด์ฉ์ด
๊ฐฑ์ ๋๋ ๋ฐฉ์์ผ๋ก 1:N ์์กด์ฑ์ ์ ์ํ๋ค.
- delegate๋ ์ธ๋ถ์์ ํธ์ถ์ด ๊ฐ๋ฅํ์ง๋ง, event๋ ํธ์ถ์ด ๋ถ๊ฐ๋ฅํ๋ค. (๊ตฌ๋ ์ ์ฒญ๋ง ๊ฐ๋ฅ)
Event ์์ฉ์ ์ํ InputManager ์์ฑusing System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace CSharpStudy { internal class InputManager { // delegate์ event์ ์ ๊ทผ ์ ํ ํ์ ์๋ ๋์ผํ๊ฒ ์ค์ public delegate void OnInputKey(); public event OnInputKey InputKey; public void Update() { if (Console.KeyAvailable == false) return; ConsoleKeyInfo info = Console.ReadKey(); if (info.Key == ConsoleKey.A) { // ํด๋น event๋ฅผ ๊ตฌ๋ ์ ์ฒญํ ๊ตฌ๋ ์๋ค์๊ฒ ์๋ ค์ค๋ค. InputKey(); } } } }โ
Event ์์ฉusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { static void Main(string[] args) { static void OnInputTest() { Console.WriteLine("Input Received!"); } InputManager inputManager = new InputManager(); inputManager.InputKey += OnInputTest; // OnInputTest ๋ฉ์๋๊ฐ InputKey event๋ฅผ ๊ตฌ๋ ์ ์ฒญ while (true) { inputManager.Update(); // event๋ ์ธ๋ถ์์ ํธ์ถ์ด ๋ถ๊ฐ๋ฅ (delegate์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ) // inputManager.InputKey(); } } } }โ
# Lambda (๋๋ค์)
- Lambda ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๋์ฒด๋ก ๊ฐ๊ฒฐํ๊ณ ๊ฐ๋ ์ฑ์ด ๋์ ์ฝ๋ ์์ฑ์ ์ํด ์ฌ์ฉ๋๋ค.
~> ๋ํ ๋ณต์กํ ์ฝ๋๋ฅผ ๋์ฑ ์ฝ๊ฒ ์์ฑํ์ฌ ๊ฐ๋ฐ์์ ์์ฐ์ ์ ๋์ฌ์ฃผ๊ณ , ์ฝ๋์ ์ ์ง ๋ณด์์ฑ์ ๋์ผ ์ ์๋ค.
๋ฌด๋ช ํจ์ ๋ฐ Lambda ์์ฉusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { enum ItemType { Weapon, Armor, Amulet, Ring } enum Rarity { Normal, Uncommon, Rare } class Item { public ItemType itemType; public Rarity rarity; } class Program { static List<Item> _items = new List<Item>(); delegate bool ItemSelector(Item item); static Item FindItem(ItemSelector selector) { foreach (Item item in _items) { if (selector(item)) return item; } return null; } static void Main(string[] args) { _items.Add(new Item() { itemType = ItemType.Weapon, rarity = Rarity.Normal }); _items.Add(new Item() { itemType = ItemType.Armor, rarity = Rarity.Uncommon }); _items.Add(new Item() { itemType = ItemType.Ring, rarity = Rarity.Rare }); // Anonymous Function (๋ฌด๋ช ํจ์ or ์ต๋ช ํจ์) Item item = FindItem(delegate (Item item) { return item.itemType == ItemType.Weapon; }); // Lambda (๋๋ค์) Item item2 = FindItem((Item item) => { return item.itemType == ItemType.Weapon; }); } } }โ
Func ๋ฐ Lambda ์์ฉusing System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { enum ItemType { Weapon, Armor, Amulet, Ring } enum Rarity { Normal, Uncommon, Rare } class Item { public ItemType itemType; public Rarity rarity; } class Program { static List<Item> _items = new List<Item>(); static Item FindItem(Func<Item, bool> selector) { foreach (Item item in _items) { if (selector(item)) return item; } return null; } static void Main(string[] args) { _items.Add(new Item() { itemType = ItemType.Weapon, rarity = Rarity.Normal }); _items.Add(new Item() { itemType = ItemType.Armor, rarity = Rarity.Uncommon }); _items.Add(new Item() { itemType = ItemType.Ring, rarity = Rarity.Rare }); // Anonymous Function (๋ฌด๋ช ํจ์ or ์ต๋ช ํจ์) Item item = FindItem(delegate (Item item) { return item.itemType == ItemType.Weapon; }); // Lambda (๋๋ค์) Item item2 = FindItem((Item item) => { return item.itemType == ItemType.Weapon; }); } } }โ
# Exception (์์ธ ์ฒ๋ฆฌ)
- Exception์ throw-try-catch-finally ๋ฌธ์ ํตํด ์ฌ์ฉํ ์ ์๋ค.
~> throw ๋ฌธ์ ํตํด ์์ธ๋ฅผ ๋์ง๋ค.
~> try ๋ฌธ์ ์์ธ๊ฐ ๋ฐ์ํ ์ ์๋ ์์ค์ฝ๋๋ฅผ ์์ฑํ๋ค.
~> catch ๋ฌธ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ์์ค์ฝ๋๋ฅผ ์์ฑํ๋ค.
~> finally ๋ฌธ์ ์์ธ ๋ฐ์ ์ฌ๋ถ์ ์๊ด์์ด ํญ์ ์คํ๋๋ ์์ค์ฝ๋๋ฅผ ์์ฑํ๋ค.
- ๋ฐ์ํ ์์ธ๊ฐ ํน์ catch ๋ฌธ์ ํด๋นํ ๊ฒฝ์ฐ ํด๋น catch ๋ฌธ์ ์ ์ธํ ๋๋จธ์ง catch ๋ฌธ์ ์คํ๋์ง ์๋๋ค.
- ๋ชจ๋ ์์ธ๋ Exception Class๋ฅผ ์์ ๋ฐ๋๋ค.
~> ๋ฐ๋ผ์ catch ๋ฌธ ๊ฐ์ ์์๊ฐ ์ค์ํ๋ค.
(Exception catch๋ฌธ์ด catch๋ฌธ ์ค ๊ฐ์ฅ ์์ ์์นํ ๊ฒฝ์ฐ ์๋์ catch๋ฌธ๋ค์ ํ์ ์คํ๋์ง X)
- ๊ฒ์ ์ ๊ณ์์ ๊ฒ์ Logic์ ๋ํด์๋ Exception ์ ์ ์ฌ์ฉํ์ง X
~> Exception ์ ์ฌ์ฉํ์ฌ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ๋ณด๋ค๋ Crash๋ฅผ ํตํ ์ค๋ฅ ์์ ์ด ๋์ฑ ์ค์ํ๋ค.
Exception ์์ฉusing System.ComponentModel; using System.Diagnostics.Tracing; using System.Numerics; namespace CSharpStudy { class Program { class TestException : Exception { int a, b, result; public TestException() { this.a = 10; this.b = 0; this.result = a / b; } } static void Main(string[] args) { try { throw new TestException(); } catch (DivideByZeroException e) { Console.WriteLine("0์ผ๋ก ๋๋ ์ ์์ต๋๋ค!"); } catch (Exception e) { Console.WriteLine("๋ ๋ค๋ฅธ ์์ธ๊ฐ ๋ฐ์ํ์ต๋๋ค!"); } finally { Console.WriteLine("๋ฐ๋์ ์คํ๋๋ ๊ตฌ๋ฌธ!"); } } } }โ
# Reflection (๋ฆฌํ๋ ์ )
- C#์ Reflection ๊ธฐ๋ฅ์ ์ง์ํ๋ค. ์ด๋ ๊ฐ์ฒด(Instance)๋ฅผ ํ ๋๋ก ๋ฐ์ดํฐํ์ ์ ๋ฉํ์ ์ธ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ธฐ๋ฒ์ด๋ค.
~> Reflection์ ์กฐ์ฌ, Instance ์์ฑ, ๊ธฐ์กด ๊ฐ์ฒด์์ ํ์์ ๊ฐ์ ธ์ ํธ์ถ, ์ ๊ทผ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
~> using System.Reflection; ์ ํตํด Reflection ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ค.
- Attribute๋ ์ฝ๋์ ๋ํ ๋ถ๊ฐ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๊ณ ์ฝ์ ์ ์๋ ๊ธฐ๋ฅ์ด๋ค.
~> ์ฃผ์์ ์ฌ๋์ด ์์ฑํ๊ณ ์ฌ๋์ด ์ฝ๋ ์ ๋ณด๋ผ๋ฉด, Attribute๋ ์ฌ๋์ด ์์ฑํ๊ณ ์ปดํจํฐ๊ฐ ์ฝ๋ ์ ๋ณด์ด๋ค.
~> Attribute๋ Metadata ํ์์ผ๋ก ์ ์ฅ๋๋ฉฐ, Compile time, Runtime ์์๋ ์ปดํจํฐ์๊ฒ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
~> ๋ฏธ๋ฆฌ ๊ตฌํ๋ Attribute๋ ์กด์ฌํ๋ฉฐ, ์ง์ Attribute๋ฅผ ๋ง๋ค ์๋ ์๋ค.
(Unity์์ ์์ฃผ ์ฌ์ฉํ๋ Attribute๋ ๋ํ์ ์ผ๋ก [ SerializeField ] ๊ฐ ์กด์ฌ)
Reflection ๋ฐ Attribute ์์ฉusing System.ComponentModel; using System.Diagnostics.Tracing; using System.Numerics; using System.Reflection; namespace CSharpStudy { class Program { class Important : System.Attribute // Custom Attribute๋ System.Attribute๋ฅผ ์์ ๋ฐ์ ๊ตฌํ { string msg; public Important(string msg) { this.msg = msg; } } class Monster { [Important("My Important variable")] public int hp; protected int attack; private float speed; void Attack() { } } static void Main(string[] args) { // Reflection : X-Ray Monster monster = new Monster(); Type type = monster.GetType(); FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); foreach (FieldInfo field in fields) { string access = "None"; if (field.IsPublic) access = "Public"; else if (field.IsPrivate) access = "Private"; var attributes = field.GetCustomAttributes(); Console.WriteLine($"{access} {field.FieldType.Name} {field.Name}"); } } } }โ
# Nullable (๋๋ฌ๋ธ)
- Nullable์ Null์ ๊ฐ์ง ์ ์๋ ๋ฐ์ดํฐ ํ์ ์ Null์ ๊ฐ์ง ์ ์๋ ํ์ ์ผ๋ก ๋ง๋ ์๋ก์ด ํ์ ์ด๋ค.
~> ์ผ๋ฐ์ ์ผ๋ก ๊ฐ ํ์ ๋ค (int, double, bool, struct ...) ์ด Null์ ๊ฐ์ง ์ ์๋ค.
Nullable ์์ฉusing System.ComponentModel; using System.Diagnostics.Tracing; using System.Numerics; using System.Reflection; namespace CSharpStudy { class Monster { public int Id { get; set; } } class Program { static void Main(string[] args) { // Nullable -> Null + able int? number = null; int value; Monster monster = null; // int number์ Null ํ์ธ ๋ฐฉ๋ฒ #1 if (number != null) { value = number.Value; } // int number์ Null ํ์ธ ๋ฐฉ๋ฒ #2 if (number.HasValue) { value = number.Value; } // int number์ Null ํ์ธ ๋ฐฉ๋ฒ #3 value = number ?? 0; // number๊ฐ Null์ด ์๋ ๊ฒฝ์ฐ ํด๋น ๊ฐ์ผ๋ก, Null์ผ ๊ฒฝ์ฐ 0์ผ๋ก ์ด๊ธฐํ // ์ฐธ์กฐ ํ์ ์ธ class์์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. // Monster monster์ Null ํ์ธ ๋ฐฉ๋ฒ #1 (์๋์ ์ฃผ์ ์ฒ๋ฆฌ๋ ์ฝ๋๋ค์ ํ ์ค๋ก ๋๋ผ ์ ์๋ค.) int? id = monster?.Id; // monster๊ฐ Null์ด ์๋ ๊ฒฝ์ฐ ํด๋น ๊ฐ์ผ๋ก, Null์ผ ๊ฒฝ์ฐ null๋ก ์ด๊ธฐํ // if (monster != null) // int id = monster.Id; // else // int id = 0; } } }โ