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

310 lines
9.5 KiB
C#

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("재정의 불가 매소드");
}