310 lines
9.5 KiB
C#
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("재정의 불가 매소드");
|
|
} |