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 x);도 가능 // Action과 Func 대리자 // Action: 반환값이 없는 대리자 void // Func: 반환값이 있는 대리자 //delegate void Action(); //delegate int Func(int x); // 이벤트 대리자 public event EventHandler 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 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(); } /// 0으로 나누기 예외 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) } /// /// • 열거자: 컬렉션을 순회하기 위한 패턴/인터페이스입니다(IEnumerable, IEnumerator). /// foreach가 내부적으로 사용하며, MoveNext(), Current, Reset() 메서드로 현재 위치를 추적합니다. /// C#에서는 yield return/yield break로 열거자를 쉽게 구현합니다. /// /// /// IEnumerable GetColors(bool isStop)// 열거자 메서드 { yield return "Red"; yield return "Green"; if(isStop) yield break; // 열거자 종료 retuer 0과 같음 yield return "Blue"; } /// /// 피보나치 수열 열거자 메서드 /// /// /// IEnumerable 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; } } /// /// 짝수만 반환하는 열거자 메서드 /// /// /// IEnumerable EvenNumbersOnly(IEnumerable 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; } }