start commit

This commit is contained in:
2026-03-01 13:38:37 +09:00
commit 0380675031
528 changed files with 32895 additions and 0 deletions

310
Assets/Scripts/Chapter2.cs Normal file
View File

@@ -0,0 +1,310 @@
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
public class Chapter2 : MonoBehaviour
{
// const와 readonly 의 차이
// const는 기본적으로 static 포함 그리고 기본변수에 만 사용가능
const int MyConstInt = 1000;
readonly List<int> ints = null;
private decimal myDecimal1, myDecimal2;
// get 간소화
public decimal MyDecimal => myDecimal1 * myDecimal2;
// get,set 간소화
public int MyProperty { get; set; } = 2025;
// 범위 지정
public decimal MyDecimal2
{
get => myDecimal1;
private set => myDecimal1 += value;
}
void Start()
{
Panda panda1 = new Panda("Bao Bao");
Panda panda2 = new Panda("Mei Xiang");
Panda panda3 = new Panda("Tian Tian");
Debug.Log("Panda Population: " + Panda.Population);
int a = int.MaxValue;
Debug.Log("Max Int: " + a);
//int b= checked(a + 1); // 오버플로우 발생시 예외 발생
//int b = unchecked(a + 1); // 오버플로우 발생시 예외 발생하지 않음
int b = a + 1; // 기본적으로 unchecked 상태
Debug.Log("Overflowed Int: " + b);
decimal c = decimal.MaxValue;// 10^28 -1 //정확도가 높지만 double보다 10배 느림
double e = double.MaxValue;// 10^308 -1 // 부동소수점 연산에 적합
float d = float.PositiveInfinity;// 양의 무한대
Debug.Log("Max Decimal: " + c);
Debug.Log("Max Double: " + e);
Debug.Log("Positive Infinity Float: " + d);// Infinity
bool isRaining = false; // 1바이트를 사용한다
BitArray bits = new BitArray(1);// 1비트만 사용
bits[0] = true;// 기본값은 false
Debug.Log("Is it raining? " + bits[0]);
StartCoroutine(WaitAndPrint());
Debug.Log("Here's a tab:\t 탭");
string filePath = @"C:\Users\Username\Documents\UnityProjects";// 이스케이프 시퀀스를 무시 @안에는 모든 문자가 일반 문자로 처리됨
Debug.Log("File Path: " + filePath);
string multiLine = @"This is a
multi-line string.
It preserves line breaks and ""spaces"".";
Debug.Log("Multi-line String: " + multiLine);// 파이썬의 ''' '''와 유사 근데 "는 두번 써야함
// $와 응용하면
string testTxt = $@"This is a test file path:
{filePath}
And here's a tab character:\tEnd of tab.";
Debug.Log("Test Text: " + testTxt);
// [,]과 [][]의 차이
// 다차원 배열 (고정 크기 직사각형)
int[,] rect = new int[2, 3];
rect[0, 0] = 1;
rect[1, 2] = 9;
// 재그드 배열 (행마다 길이가 다를 수 있음)
int[][] jagged = new int[2][];
jagged[0] = new int[3]; // 길이 3
jagged[1] = new int[1]; // 길이 1
jagged[0][0] = 1;
jagged[1][0] = 9;
// static 필드와 배열은 기본으로 0으로 초기화됨
Debug.Log("Static Int: " + staticInt);
Debug.Log("myArrar 5: " + myArray[4]);
// string과 같은 참조형식은 null로 초기화됨
decimal myD = default(decimal); // 0 //default와 동일
decimal myD2;
Debug.Log("Default Decimal: " + myD);
//Debug.Log("Default Decimal 2: " + myD2);// 지역변수는 반드시 초기화 해야함
//매계변수로 값을 복사 하는게 아닌 참조를 복사 하는게 있는데 입력은 ref, 출력은 out
// out를 사용하면 여러개의 반환값을 흉내낼 수 있음
int refValue = 10;// ref는 반드시 초기화 해야함
TestRef(ref refValue);
Debug.Log("Ref Value after TestRef: " + refValue);
int outValue1 = 20;// out는 초기화 하지 않아도 됨
TestOut(out outValue1, out refValue);
Debug.Log("Out Value1 after TestOut: " + outValue1);
Debug.Log("Out Value2 after TestOut: " + refValue);
//가변 매개변수 params
int sum1 = MySum(1, 2, 3);
Debug.Log("Sum1: " + sum1);
// 기본값 필드
MyTestBasicNumber();
// 명명된 인수
MyTestBasicNumber(20, y: 20.5f, z: "안녕하세요");
MyTestBasicNumber(y: 15.5f, x: 20, z: "순서변경");
// 매개변수의 순서가 달라도 명명된 인수를 사용하면 문제 없음
// 매개변수가 많아 지면 나름 직관적임
string testNullValue = null;
string testNonNullValue = testNullValue ?? "null 값입니다.";// null 병합 연산자
Debug.Log("Test Null Value: " + testNonNullValue);
Debug.Log("Test null value: " + testNullValue?.ToString()); //null 조건부 연산자
//Debug.Log("Test null value: " + testNullValue.ToString()); // null 포인트 에러 발생
//응용
Debug.Log("Test null value: " + (testNullValue?.ToString() ?? "null 이였슴")); // () 필수
// foreach string도 밸열로 볼수 있어 이런식으로 가능하다
foreach (char ch in "안녕하세요")
{
Debug.Log(ch);
}
// nameof 변수의 이름을 확인
Debug.Log("myDecimal1 name : " + nameof(myDecimal1));
object obj = new Panda("Bao Bao");
// 방법 1: is 패턴
if (obj is Panda panda)
{
Debug.Log($"다운캐스팅 성공: {panda.Name}");
}
//가상 함수 사용하기
MyAsset myAsset = new MyAsset();
Debug.Log(myAsset.ClassName);
Debug.Log(myAsset.Liability);
// base test 생성자 순서 확인
MyAsset myasset = new MyAsset(1);
MyAsset2 myAsset2 = new MyAsset2();
Debug.Log(myAsset2.NetValue);
Asset2 asset2 = myAsset2;// 업스케일 후
// overrider와 new 차이
asset2.MyOverrider();// 재정의 된 작식 객체를 출력
asset2.MyNew();// 부모객체를 출력한다
// sealed 로 재정의 봉인 (매소드 및 클래스에 사용가능)
asset2.MySealed();//자식 객체를 출력
//재정의 불가 매소드 출력
MyWindowApi();// 윈도우 API 호출
}
// extern 키워드와 DllImport 어트리뷰트를 사용하여
// C#에서 네이티브 코드를 호출할 수 있음
// Windows API의 MessageBox 함수 호출
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
[ContextMenu("MY Window Open")]
//[ContextMenu("윈도우 api를 사용하여 창 생성")]
public static void MyWindowApi()
{
global::System.IntPtr owner = IntPtr.Zero; // :: 를 사용하여 명시적으로 해당 System 사용 명시
MessageBox(owner, "안녕하세요", "테스트", 0);
}
void TestRef(ref int value)
{
value += 5;
}
void TestOut(out int value1,out int value2)
{
value1 = 100;
value2 = 200;
}
int MySum(params int[] numbers)// 배열 형태로만 전달 가능
{
int sum = 0;
foreach (int num in numbers)
{
sum += num;
}
return sum;
}
//int MySum2(params List<int> numbers)// List 형태로 불가
//{// C#9에서는 사용 불가 C# 13부터 가능
// int sum = 0;
// foreach (int num in numbers)
// {
// sum += num;
// }
// return sum;
//}
// 기본값 필드
void MyTestBasicNumber(int x= 10, float y = 5.5f, string z = "Hello")
{
Debug.Log($"x: {x}, y: {y}, z: {z}");
}
// static 필드와 배열은 기본으로 0으로 초기화됨
static int staticInt;
int[] myArray = new int[5];
/// <summary>
/// 1초 뒤에 호출되는 코루틴 메서드
/// </summary>
///
public System.Collections.IEnumerator WaitAndPrint()
{
yield return new WaitForSeconds(1f);
Console.Write('\a'); // 아직 유니티 콘솔에서 소리가 나지 않음(비프음)
Debug.Log("1 second has passed.");
}
// Update is called once per frame
void Update()
{
}
}
class Panda
{
public string Name;
public static int Population = 0;
/// <summary>
/// 클래스 호출시 증가하는 생성자
/// </summary>
/// <param name="name">
/// 이름
/// </param>
public Panda(string name)
{
Name = name;
Population = checked(Population++);// checked 키워드는 오버플로우 발생시 예외를 발생시킴
}
}
class Asset
{
public string name;
/// <summary>
/// 가상 멤버 함수 (인터페이스 처럼 강제가 아니다 재정의 안해도 됨)
/// </summary>
public virtual decimal Liability => 0;
/// <summary>
/// 일반 함수 재정의 불가
/// </summary>
public decimal Libility2 => 0;
int x = 1;
public Asset(int x) => Debug.Log("this.x + x : " + (this.x+x));
// 기본 생성자 생성
public Asset() => Debug.Log("Asset 기본 생성자");
}
/// <summary>
/// 추상 클레스 구현은 없고 재정의 필수
/// </summary>
abstract class Asset2
{
public abstract decimal NetValue { get; }
// overrider, new test
public virtual void MyOverrider() => Debug.Log("Asset2 Overrider");
public virtual void MyNew() => Debug.Log("Asset2 New");
// sealed test 함수
public virtual void MySealed() => Debug.Log("Asset2 sealed");
}
class MyAsset : Asset
{
public override decimal Liability => base.Liability;
public string ClassName { get; set; } = nameof(MyAsset);
//public override decimal Liability2 =>base.Libility2; //컴파일 에러
public MyAsset(int x) : base(x) => Debug.Log("MyAsset 에서 base 실행");
// base(x)로 부모객체의 생성자를 먼저 실행하고 나중에 실행된다
// 생성자를 만들어서 기본 생성자 필수 생성
public MyAsset() => Debug.Log("MyAsset 기본 생성자");
}
class MyAsset2 : Asset2
{
public override decimal NetValue => 2025;
// 재정의와 숨기기
public override void MyOverrider() => Debug.Log("MyAsset2 Overrider");
public new void MyNew() => Debug.Log("MyAsset2 New");
// 재정의 봉인
public sealed override void MySealed() => Debug.Log("재정의 불가 매소드");
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f749f7d6b10648445b8c3aa7d209ac41

181
Assets/Scripts/Chapter3.cs Normal file
View File

@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Chapter3 : MonoBehaviour, IEnumerator
{
int count = 11; //기본적으로 접근지정자는 private
// 인터페이스 구현
public bool MoveNext()=> --count >=0;// count를 1감소 시키고 0이상이면 true 반환
public object Current => count;// 현재 count 값 반환
public void Reset() => count = 11;// count 값을 11로 초기화
// enum은 명시적으로 작성할수 있고 암시적으로 작성할수 있다.
public enum BorderSide : byte// enum의 기본 자료형은 int 이다.
{
Left = 1,
Right, // 2
Top = 4,
Bottom // 5 바로 앞의 값을 기준으로 1씩 증가
}
// [Flags] // 비트 플래그로 사용하기 위한 어트리뷰트
// 2의 제곱수로 저장하는 건 Flags를 사용하는게 관례이다
[Flags] // 있어도 되고 없어도 되지만 비트 플래그를 사용시 명시적으로 표시하기 위해 사용
public enum FlagsEnum : byte
{
None = 0,
A = 1 << 0, // 1
B = 1 << 1, // 2
C = 1 << 2, // 4
D = 1 << 3 // 8
}
void Start()
{
// FlagsEnum 모두 출력 하기
foreach (FlagsEnum flag in Enum.GetValues(typeof(FlagsEnum)))
{
Debug.Log($"Flag: {flag}, Value: {(byte)flag}");
}
// Stack 제네릭 클래스 사용 예제
Stack<int> intStack = new Stack<int>();
intStack.Push(10);
intStack.Push(20);
Debug.Log(intStack.Pop()); // 20 출력
Debug.Log(intStack.Pop()); // 10 출력
// Swap 제네릭 메서드 사용 예제
int x = 5, y = 10;
Debug.Log($"Before Swap: x = {x}, y = {y}");
Swap<int>(ref x, ref y);
Debug.Log($"After Swap: x = {x}, y = {y}");
// Initialize 제네릭 제약조건 메서드 사용 예제
MyClass[] myClassArray = new MyClass[3];
Initialize<MyClass>(myClassArray);
foreach (var item in myClassArray)
{
Debug.Log(item != null ? $"{item}" : "Null");
}
// Initialize2 제네릭 제약조건 메서드 사용 예제
Initialize2<string>(new string[] { "Hello", "World", "!" });
}
/// <summary>
/// 제네릭을 사용한 Swap 메서드
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="a"></param>
/// <param name="b"></param>
void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
/// <summary>
/// 제네릭 제약조건을 사용하여 new() 생성자를 호출할수 있는 메서드
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Array"></param>
void Initialize<T>(T[] Array) where T : new() // class, struct 등 참조형식, 값형식 제약조건도 사용 가능
{
for (int i = 0; i < Array.Length; i++)
{
Array[i] = new T();
}
}
void Initialize2<T>(T[] Array) where T : notnull // null 값을 허용하지 않는 제약조건
{
for (int i = 0; i < Array.Length; i++)
{
Debug.Log(Array[i]);
}
}
/// <summary>
/// 확작된 제네릭 메서드 사용
/// </summary>
SpecialStack<int> specialStack = new SpecialStack<int>();
void Update()
{
if (Keyboard.current.wKey.isPressed)
{
specialStack.PushWithLog(UnityEngine.Random.Range(1, 100));
}
if (Keyboard.current.sKey.isPressed)
{
specialStack.PopWithLog();
}
}
/// <summary>
/// 재귀적 제네릭 메서드
/// </summary>
Balloon redBalloon = new Balloon { Color = "Red" };
Balloon blueBalloon = new Balloon { Color = "Blue" };
[ContextMenu("CompareBalloons")] /// 유니티 에디터에서 우클릭 실행용
public void CompareBalloons()
{
bool areEqual = redBalloon.Equals(blueBalloon);
Debug.Log($"Are balloons equal? {areEqual}");// False 출력
}
}
/// <summary>
/// 인터페이스는 기본적으로 public 이다 변수,함수...
/// </summary>
interface IEnumerator // 인터페이스는 기본적으로 public 이다
{
bool MoveNext();
object Current { get; }
void Reset();
}
/// <summary>
/// 제네릭은 탬플릿화된 클래스 또는 함수이다.
/// </summary>
/// <typeparam name="T"></typeparam>
class Stack<T>// 클래스는 기본적으로 internal 이다
{
int position;
T[] items = new T[100];
public void Push(T i) => items[position++] = i;
public T Pop() => items[--position];
}
/// <summary>
/// 파생된 제네릭 클래스를 상속하는 제네릭 클래스
/// </summary>
/// <typeparam name="T"></typeparam>
class SpecialStack<T> : Stack<T>
{
public void PushWithLog(T value)
{
Debug.Log($"Push: {value}");
Push(value);
}
public T PopWithLog()
{
T value = Pop();
Debug.Log($"Pop: {value}");
return value;
}
}
interface IEquatable<T> { bool Equals (T obj ); }/// 제네릭 인터페이스
class Balloon : IEquatable<Balloon> // 제네릭 인터페이스 구현
{
public string Color { get; set; }
public bool Equals(Balloon other)
{
return this.Color == other.Color;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e8ab143db8fc9dd4b961d616c5344063

186
Assets/Scripts/Chapter4.cs Normal file
View File

@@ -0,0 +1,186 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Xml.Serialization;
using UnityEditor.XR;
using UnityEngine;
using UnityEngine.EventSystems;
public class Chapter4 : MonoBehaviour
{
// 4장 고급 c# 프로그래밍
delegate int Transform(int x);
//제네릭을 사용하여
// delegate T Transform<T>(T x);도 가능
// Action과 Func 대리자
// Action: 반환값이 없는 대리자 void
// Func: 반환값이 있는 대리자
//delegate void Action();
//delegate int Func(int x);
// 이벤트 대리자
public event EventHandler<PriceChangedEventArgs> PriceChanged;
// 보호된 가상 메서드로 이벤트 호출
protected virtual void OnPriceChanged(decimal lastPrice, decimal newPrice)
{// 이름에 "On" 접두사 붙이기 관행이 있다
PriceChanged?.Invoke(this, new PriceChangedEventArgs(lastPrice, newPrice));
}
int Square(int x) => x * x;
void Start()
{
Transform t = Square;
Debug.Log(t(3)); // 9 출력
// ?.invoke 는 널 체크 (null 이면 호출 안함)
Debug.Log(t?.Invoke(4)); // 16 출력
// 람다로 임멱 함술 축가
t += x => x + x;
Debug.Log(t(3));// 6 출력 (마지막 메서드 반환값)
// 델리게이트 메소드 제거
t -= Square;
t -= x => x + x;// 람다식은 익명 메서드이므로 제거 불가
Debug.Log(t?.Invoke(5)); // 10 출력
// Action
Action a = () => Debug.Log("Action delegate called");
a();
// Func
Func<int, int> f = x => x * x;
Debug.Log(f(6)); // 36 출력
// 이벤트 사용 예제
PriceChanged += (sender, e) =>
{
Debug.Log($"Price changed from {e.LastPrice} to {e.NewPrice}");
};
OnPriceChanged(100m, 120m);// 이벤트 발생
// 출력: Price changed from 100 to 120
OnPriceChanged(100m, 120m);// 이벤트 발생
// 같은 갑이라도 이벤트 발생
try
{
Debug.Log(0/2); // 2/0 는 컴파일러에서 막는다
// 예외 던지기
throw new DivideByZeroException();
}
/// <exception cref="DivideByZeroException">0으로 나누기 예외</exception>
catch (DivideByZeroException ex) //when (ex.InnerException != null)
{// when 필터링 ex.InnerException 가 null 이 아닐 때만 잡음 (true 면 잡음)(false 면 무시)
Debug.Log("0으로 나누기 에러 발생");
//throw; // 예외 다시 던지기
// 예외처리 못 받고 에러 로그 출력
}
catch (Exception ex)
{
Debug.Log($"예외 발생: {ex.Message}");
}
finally
{
Debug.Log("예외가 되든 안되든 동작은 함 ㅋㅋ");
// 주로 네트워크 연결 해제, 파일 닫기 등 정리 코드 작성
}
bool isStop = true;
foreach (string i in GetColors(isStop))
{
Debug.Log(i);
}
foreach(int fib in EvenNumbersOnly(Fibs(6)))
Debug.Log(fib);
int? aa = null;
int bb = 7;
int? cc = aa + bb;
//하나가 null이면 null 반환(SQL도 동일)
Debug.Log(cc); // null 출력
info();
#pragma warning disable 414 // 414라는 경고 무시 (사용되지 않는 필드)
Debug.LogError("대충 경고 메시지");// 이건 무시되지 안는다
#pragma warning restore 414 // 414라는 경고 다시 켜기
}
static void info(
[CallerMemberName] string memberNamer = null,
[CallerFilePath] string filePath = null,
[CallerLineNumber] int lienNumber = 0
)
{
Debug.Log(memberNamer); //실행 메소드 이름
Debug.Log(filePath); // 소스코드 경로
Debug.Log(lienNumber); // 호출된 라인넘버(103)
}
/// <summary>
/// • 열거자: 컬렉션을 순회하기 위한 패턴/인터페이스입니다(IEnumerable, IEnumerator).
/// foreach가 내부적으로 사용하며, MoveNext(), Current, Reset() 메서드로 현재 위치를 추적합니다.
/// C#에서는 yield return/yield break로 열거자를 쉽게 구현합니다.
/// </summary>
/// <param name="isStop"></param>
/// <returns></returns>
IEnumerable<string> GetColors(bool isStop)// 열거자 메서드
{
yield return "Red";
yield return "Green";
if(isStop)
yield break; // 열거자 종료 retuer 0과 같음
yield return "Blue";
}
/// <summary>
/// 피보나치 수열 열거자 메서드
/// </summary>
/// <param name="fibCount"></param>
/// <returns></returns>
IEnumerable<int> Fibs(int fibCount)
{
for(int i=0, prevFib = 1, curFib = 1; i < fibCount; i++)
{
yield return prevFib;
int newFib=prevFib + curFib;
prevFib = curFib;
curFib = newFib;
}
}
/// <summary>
/// 짝수만 반환하는 열거자 메서드
/// </summary>
/// <param name="sequence"></param>
/// <returns></returns>
IEnumerable<int> EvenNumbersOnly(IEnumerable<int> sequence)
{
foreach(int x in sequence)
{
if ((x % 2) == 0)
{
yield return x;
}
}
}
}
//[ObsoleteAttribute("이 클래스는 가격 변경 이벤트에 사용됩니다. 더 이상 사용되지 않습니다.")] // 클래스에 대한 경고 메시지 아래와 동일
[Obsolete("이 클래스는 가격 변경 이벤트에 사용됩니다. 더 이상 사용되지 않습니다.")] // 클래스에 대한 경고 메시지
public class PriceChangedEventArgs : System.EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
{
LastPrice = lastPrice;
NewPrice = newPrice;
}
}
public class CustomerEntity
{
[XmlElement("MyCustomer", Namespace = "http://oreilly.com"), Obsolete("사용 안함")]
public string Customer { get; set; }
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8f98ef98a7a9c184f8bb832e79aa1405

View File

@@ -0,0 +1,16 @@
using UnityEngine;
public class Chapter5 : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7dbdd1beccc3e0745a8daed806a4165f

View File

@@ -0,0 +1,3 @@
internal class MyClass
{
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b4dc7956ff039dd469b7a0ad7fd24b91