Files
ScriptsRuning/Assets/Scripts/Chapter3.cs
2026-03-01 13:38:37 +09:00

182 lines
4.9 KiB
C#

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;
}
}