'프로그래밍 언어/C#'에 해당되는 글 17건

  1. 2019.12.05 C# 코루틴
  2. 2019.12.05 C# 예외처리
  3. 2019.12.05 C# Action과 Func
  4. 2019.12.05 C# 람다식
  5. 2019.12.05 C# 형식 매개변수 T
  6. 2019.12.05 C# 인덱서
  7. 2019.12.05 C# 프로퍼티
  8. 2019.12.05 C# 상속

유니티는 단일 쓰레드로 동작한다. 하지만 코루틴을 사용하면 쓰레드를 사용하지 않고 멀티 태스킹을 구현 할 수 있다. C#에서 이터레이터는 프로그래머가 IEnumerator 를 구현할 수있도록 돕는 기능이다. 열거형의 MoveNext() 를호출 할 때마다. 해당하는 다음 값을 반환한다. 일반적으로 함수가 호출되서 끝나는 서브루틴의 개념과 달리 yield return 을 사용함으로써 그 위치를 기억하고 다음 호출 때 그곳부터 다음을 실핼 할 수있도록 하는 것이다. 그래서 여러개의 코루틴을 동작시키고 각기다른 시점에 yield가 반환되도록 한다면 마치 어러개의 쓰래드가 동시에 동작하는것과 같은 효과가 나타난다

 

아래의 예제는 코루틴을 실행할 때 함수를 직접 실행하는 방법과 함수의 이름 즉 스트링을 이용해 호출 하는 방법 두가지를 테스트 한다.

AAA(), BBB() 코루틴 함수는 1초마다 실행되며 2초 후에 코루틴은 멈추게 된다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    Coroutine coroutine1;

    void Start()
    {
        // 코루틴 실행 방법 (함수)
        // 파라미터를 여러 개 쓸 수 있다.
        coroutine1 = StartCoroutine(AAA());

        // 코루틴 실행 방법 (스트링)
        // 성능상 함수로 호출하는 것보다 느리다.
        // 파라미터를 1개만 쓸 수 있다.
        StartCoroutine("BBB");

        StartCoroutine(STOP());
    }

    IEnumerator AAA()
    {
        for(int i = 0; i < 10; i++)
        {
            print("i 의 값 = " + i);

            // 1초 마다 호출 하게 된다.
            yield return new WaitForSeconds(1f);
        }
    }

    IEnumerator BBB()
    {
        for(int j = 0; j < 10; j++)
        {
            print("j 의 값 = " + j);

            // 1초 마다 호출 하게 된다.
            yield return new WaitForSeconds(1f);
        }
    }

    IEnumerator STOP()
    {
        yield return new WaitForSeconds(2f);
        StopCoroutine(coroutine1);

        yield return new WaitForSeconds(2f);
        StopCoroutine("BBB");
    }
}

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 예외처리  (0) 2019.12.05
C# Action과 Func  (0) 2019.12.05
C# 람다식  (0) 2019.12.05
C# 형식 매개변수 T  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
Posted by 소블리애
,

프로그램을 짜다 보면 오류로 인해 프로그램이 크래쉬(죽게)된다. 오류가 나더라도 정상 동작하게 끔 바꾸어 주는 것이 예외 처리이다. try catch는 예외 처리하는 방법 중에 하나이고 catch 부분에 모든 오류를 다 출력 시킬 수도 있고 특정 오류만 들어오게 코드를 짤 수도 있다. 아래의 예제는 0으로 나눴을 때 발생하는 오류가 catch 문에 들어오게 되고 b의 값을 1로 수정하여 최종적으로 오류를 잡게 되는 코드이다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; // Exception을 사용하기 위해 선언

public class Test : MonoBehaviour
{
    int a = 5;
    int b = 0;
    int c;

    void Start()
    {
        // 컴퓨터는 0으로 나누면 오류가 발생한다.
        // 이 상태에서는 크래쉬가 나서 프로그램이 종료하게 된다.
        // c = a / b;

        // 오류가 발생 하더라도 프로그램이 죽지 않게 예외 처리를 하면 아래와 같다.
        try
        {
            c = a / b;
        }

        // Exception으로 하면 모든 오류를 잡아낸다.
        // DivideByZeroException으로 하면 0으로 나눈 오류만 잡아내게 된다.
        // catch는 여러게를 쓸수도 있다.
        catch(DivideByZeroException ie) 
        {
            
            print(ie);
            b = 1;
            c = a / b;
        }

        // 오류가 발생하든 말든 최종적으로 출력된다.
        finally
        {
            print(c);
        }
    }
}

 

또한 프로그램 로직에는 오류가 없지만 일부러 코드를 통해 오류를 발생 시킬 수도 있다. 게임이라고 생각해보자 유저의 이상 행동이 감지가 되면 오류를 발생 시키고 프로그램을 끝내도록 유도하면 될거 같다.또한 프로그램 로직에는 오류가 없지만 일부러 코드를 통해 오류를 발생시킬 수도 있다. 게임이라고 생각해보자 유저의 이상 행동이 감지가 되면 오류를 발생시키고 프로그램을 끝내도록 유도하면 될 거 같다.

 

throw new Exception("일부러 오류를 발생한다.");

 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 코루틴  (0) 2019.12.05
C# Action과 Func  (0) 2019.12.05
C# 람다식  (0) 2019.12.05
C# 형식 매개변수 T  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
Posted by 소블리애
,

델리게이트를 조금더 간편하게 쓸 수 있는 Action과 Func이 있다. 이 두개의 차이 점은 반환형이 있는냐 없느냐 이다. 우선 사용하려면 using System을 선언 해야한다.  Func는 선언시 3번째 자리가 반환 타입이다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; // Action, Func을 사용하기 위해서 필요함 


public class Test : MonoBehaviour
{
    // 내부적으로 델리게이트 선언부가 미리 만들어져 있기 때문에 델리게이트보다 쓰기 편하다.
    // 간편한 델리게이트라고 보면 된다.
    Action<int, int> myAction;

    // 3번째는 리턴 받을 자료형이다.
    // 반환 값이 있는 간편한 델리게이트라고 보면 된다.
    Func<int, int, string> myFunc;

    void Start()
    {
        myAction = (int a, int b) =>
        {
            int sum = a + b;
            print(sum);
        };

        myFunc = (int a, int b) =>
        {
            int sum = a + b; return sum + "이 리턴되었습니다.";
        };

        myAction(10, 20);
        print(myFunc(10, 20));
    }
}

 

출력 결과:

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 코루틴  (0) 2019.12.05
C# 예외처리  (0) 2019.12.05
C# 람다식  (0) 2019.12.05
C# 형식 매개변수 T  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
Posted by 소블리애
,

람다식은 무명 메소드를 단순한 계산식으로 표현한 것이다. 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    delegate void MyDelegate<T>(T a, T b);
    MyDelegate<int> myDelegate;

    void Start()
    {
        // 무명 메소드
        myDelegate += delegate(int a, int b) { print( a + b); };

        // 람다식
        myDelegate += (int a, int b) => print(a + b);

        // 람다식 매개변수 타입 생략도 가능 함 
        myDelegate += (a, b) => print(a + b);

        myDelegate(10, 20);
    }
}

 

출력 결과: 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 예외처리  (0) 2019.12.05
C# Action과 Func  (0) 2019.12.05
C# 형식 매개변수 T  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
C# 프로퍼티  (0) 2019.12.05
Posted by 소블리애
,

형식 매개변수 T는 함수에 형식을 지정하지 않아도 호출 시에 형식만 지정하면 어떤 형식이든지 다 받을 수 있다. 형식만 다른 함수의 중복성을 간편하게 만들 수 있습니다.

 

public class Test : MonoBehaviour
{
    void Print<T>(T value)
    {
        print(value);
    }

    void Start()
    {
        Print<string>("hello");
        Print<float>(3.14f);
    }
}

출력 결과: 

 

추가로 원하는 데이타 형식으로도 받을 수 있습니다. where T : struct 이렇게 뒤에 추가하면 struct 타입만 받겠다는 의미가 된다. float은 struct 형태이고 string은 class 형태이기 때문에 에러가 발생한다. 

 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# Action과 Func  (0) 2019.12.05
C# 람다식  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
C# 프로퍼티  (0) 2019.12.05
C# 상속  (0) 2019.12.05
Posted by 소블리애
,

인덱서(Indexer)는 인덱스를 이용해서 객체 내의 데이터에 접근하게 해주는 프로퍼티이다. 

 

class 클래스이름
{
    한정자 인덱서형식 this[형식 index]
    {
        get
        {
            // index를 이용하여 내부 데이터 변환
        }
        set
        {
            // index를 이용하여 내부 데이터 저장
        }
    }
}

 

코드 예제)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Record
{
    public int[] temp = new int[5];

    public int this[int index]
    {
        get
        {
            if(index >= temp.Length)
            {
                Debug.Log("인덱스가 너무 큽니다.");
                return 0;
            }
            else
            {
                return temp[index];
            }            
        }
        set
        {
            if(index >= temp.Length)
            {
                Debug.Log("인덱스가 너무 큽니다.");
            }
            else
            {
                temp[index] = value;
            }
        }
    }
}

public class Test : MonoBehaviour
{
    void Start()
    {
        Record record = new Record();
        record[3] = 5;
        record[5] = 5;
    }
}

 

출력 결과: 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 람다식  (0) 2019.12.05
C# 형식 매개변수 T  (0) 2019.12.05
C# 프로퍼티  (0) 2019.12.05
C# 상속  (0) 2019.12.05
C# 델리게이트와 이벤트  (0) 2019.12.05
Posted by 소블리애
,

보통 변수를 만들고 나서 Set, Get 함수를  구현하여 변수를 읽고 쓰고 합니다. 변수를 추가할 때 마다 매번 생성해야하는 불편함이 있었는데요. C#에서는 이를 단순화하는 프로퍼티라는 변수를 제공합니다. 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Person
{
    // 기본 프로퍼티 사용법
    private int age;
    public int Age { get { return age; } set { age = value; } }

    // 프로퍼티도 데이터 은닉화를 할 수 있다.
    private string name;
    public string Name { get { return name; } private set { name = value; } }

    // 심플 프로퍼티 사용법
    public int weight { get; set; }
}

public class Test : MonoBehaviour
{
    void Start()
    {
        Person p1 = new Person();
        p1.Age = 10;
        print(p1.Age);

        // Name의 set 프로퍼티 앞에 private 키워드를 넣었기 때문에 아래 코드는 컴파일 되지 않는다.
        //p1.Name = "가나다";

        p1.weight = 70;
        print(p1.weight);
    }
}

 

출력 결과: 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 형식 매개변수 T  (0) 2019.12.05
C# 인덱서  (0) 2019.12.05
C# 상속  (0) 2019.12.05
C# 델리게이트와 이벤트  (0) 2019.12.05
C# 구조체와 클래스 차이점  (0) 2019.12.04
Posted by 소블리애
,

상속을 설명하기 전에 부모 클래스와 자식 클래스를 두개 만들어 줍니다. 

 

Human.cs (부모 클래스)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 추상 함수를 쓰면 반드시 클래스도 추상 클래스가 되어야 한다.
abstract public class Human : MonoBehaviour
{
    protected string humanName;
    protected int humanAge;

    // 자식 클래스에서 함수 재정의를 하려면 부모클래스를 virtual로 선언해야 한다.
    protected virtual void Info()
    {
        print("나는 인간입니다.");
    }

    abstract protected void Name();
}

 

Student.cs (자식 클래스) 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Student : Human
{
    string schoolName;

    void Start()
    {
        schoolName = "티스토리";
        humanName = "소블리애";
        humanAge = 20;

        print(schoolName);
        Info();
        Name();        
    }

    // 부모 클래스의 Info함수를 재정의 한다.
    protected override void Info()
    {
        base.Info();
        print("나는 학생입니다");
    }

    // 만약 Name 함수를 재정의를 안했다면 컴파일 에러가 발생하게 된다.
    // 추상 함수는 자식 클래스에서 반드시 재정의를 해줘야 한다.
    // 프로그래머의 코드 누락을 방지하기 위한 방법.
    protected override void Name()
    {
        print(humanName);
    }
}

 

결과 화면 

위에 코드를 보면 학생은 인간임으로 논리적으로 상속이 성립합니다. 부모 클래스로 부터 상속 받은 자식 클래스는 부모에서 생성된 멤버 변수를 기본적으로 갖게 됩니다. humanName과 humanAge가 그렇습니다. 또한 자식 클래스에서 함수를 재정의 하여 쓸 수도 있습니다. 이때 반드시 부모 클래스에 가상함수(virtual)라고 알려줘야 합니다. 자식 클래스는 함수 이름 앞에 재정의(override) 키워드를 넣어주면 됩니다.

 

또한 반드시 작성해야 하는 함수(추상함수)를 갖게 되는 경우 부모 클래스에서 abstract 키워드를 함수와 클래스 앞에 넣어 줍니다. 그리고 구현 부분은 상속받은 자식 클래스에서 구현합니다. abstract를 붙여주는 이유는 해당 함수 및 클래스가 미완성인 상태를 명시 하는 것이다. 자식 클래스에서 해당 함수를 완성해야만 한다. 만약에 자식 클래스에서 구현을 하지 않았다면 컴파일 에러가 발생하게 됩니다. 이는 프로그래머가 반드시 작성해야 하는 코드임을 알려줄 수 있습니다. 

 

추가로 클래스 멤버 또는 함수에는 접근 한정자가 붙습니다. 용도는 아래와 같습니다.

 

public - 타 클래스에서 모두 사용 가능

private - 클래스의 내부에서만 사용 가능

protected - 상속 받는 자식 클래스만 사용 가능 

'프로그래밍 언어 > C#' 카테고리의 다른 글

C# 인덱서  (0) 2019.12.05
C# 프로퍼티  (0) 2019.12.05
C# 델리게이트와 이벤트  (0) 2019.12.05
C# 구조체와 클래스 차이점  (0) 2019.12.04
C# 얕은 복사와 깊은 복사  (0) 2019.12.04
Posted by 소블리애
,