[C#과 유니티, 실전 게임으로 제대로 시작하기]섹션5. 스터디
void Start(){
string str1 = "Hello";
Debug.Log(str1.Length); //str1의 길이인 5가 반환된다.
}
void Start(){
string str1 = "Hello";
Debug.Log(str1.IndexOf("e")); //0번째 H부터 시작하여 "e"인수는 1번째 순서에 있기에 1을 반환한다.
}
void Start(){
string str1 = "Hello";
Debug.Log(str1.Replace("el", "55"); //el부분을 55로 치환해주어 H55lo가 출력된다.
}
void Start(){
string str1 = "abcdef";
string[] arr = str1.Split('c'); //c를 기준으로 문자열을 나눈다.
Debug.Lof(arr.Length); //c를 기준으로 2개의 배열이 나왔기에 2가 출력된다.
Debug.Log(arr[0]); //ab가 arr[0]에 담긴다.
Debug.Log(arr[1]); //def가 arr[1]에 담긴다.
}
예시>
void Start(){
string str1 = "철수, 철불, 철목, 철석";
string[] arr = str1.Split(',');
foreach (string name in arr){ //arr배열을 하나씩 name 변수에 담는다.
Debug.Log(name); //철수 철불 철목 철석 이 따로 출력된다.
}
}
void Start(){
string str1 = "tomato";
Debug.Log(str1.SubString(2)); //인수의 숫자부터 시작하여 출력해준다. 즉, 2번째에 엤는 m부터 끝까지 출력한다. mato
Debug.Log(str1.SubString(1,3)); //1부터 3개의 문자를 출력한다. oma
Debug.Log(str1.SubString(str1.indexOf("o"),3); //o부터 3개의 문자를 반환하기에 oma가 출력된다.
}
void Start(){
// int num = 43*72;
// string str1 = "43 * 72 = num"; //str1에 들어간 num은 문자열로 취급하기 때문에 int로 선언한 num이 대입되지 않는다. 이러한 문제를 해결하기 위해 string.Format()을 사용한다.
string newStr = string.Format("43 * 72 = {0}", 43 * 72); //43*72의 값이 {0}인덱스에 들어가 3096이 출력된다.
}
예시>
void Start(){
for(int i = 2; i < 10 ; i++){
for(int j = 1 < 10 ; j++){
Debug.Log(string.Format("{0} * {1} = {2}", i, j, i*j)); //구구단이 출력된다.
}
}
}
int num = 1;
/*string str1 = (string)num; //int는 값형이고, string은 참조형이기에 형변환을 하지 못한다.*/
string str1 = num.Tostring(); //num의 값을 string으로 변환하여 str1에 담간다. str1은 문자열"1"이 된다.
int num2 = int.Parse(str1); //문자열인 "1"을 1로 반환하여 num2에 담긴다.
int num3 = float.Parse(str1); //float형으로 반환하여 1.0f가 num3에 담긴다.
객체와 상관없이 타입에 종속적인 멤버로 선언된다.
void Start(){
ExampleClass ex1 = new ExampleClass();
ExampleClass ex2 = new ExampleClass();
ex1.number = 1;
ex2.number = 2;
Debug.Log(ex1.number); //1이 출력된다.
Debug.Log(ex2.number); //2가 출력된다.
}
class ExampleClass{
public int number;
}
이 코드에서 public int number을 static으로 전환하면 ex1.number와 ex2.number에서 오류가 발생한다. ex1.number와 ex2.number 둘 다 ex1,ex2의 객체에 종속했지만 number을 static으로 전환하면 객체와 상관없이 ExampleClass에 종속된다.
void Start(){
ExampleClass.number = 1;
ExampleClass.number = 2;
Debug.Log(ExampleClass.number); //2가 출력된다.
}
class ExampleClass{
public static int number;
}
예시>
void Start(){
Member chulsoo = new Member(17,"chulsoo");
Member jisoo = new Member(18,"jisoo");
Debug.Log(Member.numberOfMembers); //2가 출력된다.
}
class Member{
public int age;
public string name;
public static int numberOfMembers; //멤버의 총 숫자
public Member(int age, string name){
this.age=age;
this.name=name;
numberOfMembers++; //생성자가 실행될 때 마다 값이 1씩 증가한다.
}
}
using System.Collections를 활용하여 배열의 비효율성을 보완하기위한 타입들이 존재한다.
void Start(){
ArrayList myAr = new ArrayList();
myAr.Add(1); //{1}
myAr.Add(36); //{1, 36}
myAr.Add("Hello"); //{1, 36, "Hello"}
Debug.Log(myAr.Count); //Count를 활용하여 myAr에 몇 개의 요소가 있는지 확인할 수 있다. 3이 출력된다.
myAr.Remove(36); //{1, "Hello"}
myAr.RemoveAt(1); //1번째 요소인 Hello가 제거된다. {1}
}
void Start(){
Hashtable myHT = new Hastable();
myHT.Add("첫 번째",1234); //"첫 번째"가 key값이고, 1234가 value값이다. "첫 번째"인덱스에 1234가 저장된다.
myHT.add(3,"안녕"); //3인덱스에 "안녕"이 저장된다.
myHT.Remove(3); //key가 3인 공간이 제가된다.
}
void Start(){
Queue myQueue = new Queue;
myQueue.Enqueue(3); //Enqueue를 활용하여 인수를 추가한다. {3}
myQueue.Enqueue(6); //{3, 6}
myQueue.Enqueue(9); //{3, 6, 9}
myQueue.Dequeue(); //Dequeue를 활용하려 인수를 제거한다. 첫 번째로 저장되었던 3이 제거된다. {6, 9}
myQueue.Dequeue(); //{9}
myQueue.Dequeue(); //{}
}
void Start(){
Stack myStack = new Stack();
myStack.Push(3); //Push를 활용하여 인수를 추가한다. {3}
myStack.Push(6); //{3, 6}
myStack.Push(9); //{3, 6, 9}
myStack.Pop(); //Pop을 활용하여 인수를 제거한다. 마지막으로 추가된던 인수가 먼저 나간다. {3, 6}
myStack.Pop(); //{3}
myStack.Pop(); //{}
}
void Start(){
Queue myQueue = new Queue;
myQueue.Enqueue(3);
myQueue.Enqueue(6);
myQueue.Enqueue(9);
myQueue.Peek(); //인수가 제거되지 않고 첫 번째 인수인 3이 출력된다.
myQueue.Peek(); //똑같이 3이 출력된다.
}
object : 모든 자료형을 담을 수 있다.
object number = 1;
object str = "asdf"; //어떤 자료형이든 담을 수 있다.
int num = 1;
object a = num; //암시적 형변환 ->박싱
object b = 5;
int num2 = (int)b; //명시적 형변환 ->언박싱
Object의 문제점
박싱과 언박싱을 수행하는 데 많은 계산 과정이 필요하다. 값 형식이 박싱되면 완전히 새로운 개체가 생성되어야 한다. 이 작업은 단순 참조 할당보다 20배나 오래 걸린다.(20배 성능이 저하된다.) 언박싱 시 캐스팅 프로세스는 할당의 4배에 달하는 시간이 소요된다.
System.Collections 네임스페이스프 클래스는 구체적 형식의 개체(int, float...)가 아니라 object 형식의 개체로 요소를 저장한다. 가능하면 System.Collections.Generic네임스페이스 또는 System.Collections.Concurrent네임스페이스의 제너릭 컬렉션을 사용한다.
C# Boxing 및 Unboxing
void Start(){
DataClass_int dc1 = new DataClass_int();
dc1.data = 1;
dc1.GetData();
DataClass_char dc2 = new DataClass_char();
dc2.data = "hello";
dc2.GetData();
}
class DataClass_int{
public int data;
public int GetData(){
return data;
}
}
class DataClass_char{
public char data;
public char GetData(){
return data;
}
}
-> 클래스를 정의할 때 미리 타입을 정했기 때문에 나중에 타입과 관련하여 수정하기 번거러움이 있다.
제네릭 : 타입을 미리 정의하지 않고 타입을 사용할 때 정의한다.
형식 매개변수 (T) : 미리 타입을 정의하지 않고 임의로 T라 타입을 정의한다.
void Start(){
DataClass<int> dc1 = new DataClass<int>;
dc1.data = 1;
dc1.GetData();
DataClass<char> dc2 = new DataClass<char>;
dc2.data = "hello";
dc2.GetData();
}
class DataClass<T>{
public T data;
public T GetData{
return data;
}
}
DataClass를 제네릭으로 선언하여 DataClass를 사용할 때 타입을 정의할 수 있도록 한다.
이와같은 방법으로 이전에 GetComponent<>를 사용한 적이 있다.
| Collection | Generic |
|---|---|
| ArrayList | List<> |
| Hastable | Dictionary<> |
| Queue | Queue<> |
| Stack | Stack<> |
void Start(){
List<int> myList = new List<int>();
myList.Add(1); //{1}
myList.Add(2); //{1, 2}
Debug.Log(myList[0]); //1이 출력된다.
//myList.Add("Hello"); -> List타입이 int이기에 오류가 난다.
myList.Remove(2); //{1}
}
void Start(){
Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("첫 번째",1234);
myDict.Add("두 번째",4567);
myDict.Remove("두 번째");
Debug.Log(myDict["첫 번째"]); //1234가 출력된다.
}
void Start(){
Queue<float> myQueue = new Queue<float>();
myQueue.Enqueue(3.0f); //{3.0}
myQueue.Enqueue(6.0f); //{3.0, 6.0}
Debug.Log(myQueue.Peek()); //3.0f가 출력된다.
myQueye.Dequeue(); //{6.0}
}
void Start(){
Stack<char> myStack = new Stack<char>();
myStack.Push('a'); //{a}
myStack.Push('b'); //{a, b}
Debug.Log(myStack.Peek()); //b가 출력된다.
myStack.Pop(); //{a}
}