ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C#] Reflection 기능으로 Method 다루기
    언어/C# 2021. 2. 19. 03:03

    유니티로 게임을 만들 때 공부한 기능이기 때문에, 내용중에 오브젝트라는 개념을 포함하고 있습니다.

     

    함수 이름을 (ballMove + 오브젝트의 번호) 로 만들었다.

    오브젝트마다 각각의 함수로 실행되어야 하기 때문!

        void ballMove21()
        {
            this.gameObject.transform.localPosition = new Vector3(100, 300, 0);
            rigid.velocity = new Vector2(speed, 0);
        }
        void ballMove22()
        {
            this.gameObject.transform.localPosition = new Vector3(100, 100, 0);
            rigid.velocity = new Vector2(speed, 0);
        }
        void ballMove23()
        {
            this.gameObject.transform.localPosition = new Vector3(100, -100, 0);
            rigid.velocity = new Vector2(speed, 0);
        }
        void ballMove24()
        {
            this.gameObject.transform.localPosition = new Vector3(100, -300, 0);
            rigid.velocity = new Vector2(speed, 0);
        }

     

    이렇게 따로 만들어진 함수때문에 아래 코드처럼 오브젝트 이름별로 if문으로 구별하여 호출해야하는 최악의 상황.

    실제 프로젝트에는 이런 함수가 10개가 더 있었다.

    if (ballNum == 21) 
    	ballMove21();
    else if (ballNum == 22)
    	ballMove22();
    else if (ballNum == 23)
    	ballMove23();
    else if (ballNum == 24)
    	ballMove24();

     

     

    오브젝트의 번호를 가져와 번호가 동일한 함수를 검색하여 호출할 수 있는 Reflection을 알게되었고, 적용했다.

    string ballNum = this.gameObject.name.Substring(7);
    
    /** Reflection기능. 함수를 string으로 호출함*/
    //메소드이름을 string으로 만들어줌
    string ballMethodName = "ballMove" + ballNum;
    
    //사용할 메소드가 있는 클래스를 객체로 생성
    BossAttackBall bab = this.gameObject.GetComponent<BossAttackBall>();
    
    //타입클래스와 Method클래스로 메소드를 실행시켜줌
    Type tp = bab.GetType();
    MethodInfo method = tp.GetMethod(ballMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    method.Invoke(bab, null);

    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance

    멤버 및 형식에 대한 검색을 수행하는 방법과 바인딩을 제어하는 플래그를 지정 (즉, Reflection 설정)

    -> Public : public 멤버를 검색에 포함하도록 지정

    -> NonPublic : public이 아닌 멤버를 검색에 포함하도록 지정
    -> Instance : 인스턴스 멤버를 검색에 포함하도록 지정

    이렇게하면 static을 제외한 모든 메서드가 검색된다.

     

     

     

    결국.. Reflection 이란

    String으로 메소드 이름을 지정해주고, 그 이름을 가진 메서드를 검색하여 실행시켜주는 기능으로 보여진다.

     

     

     

    ===

    거의 9개월 전에 만들었던 코드...

    지금 코드를 다시 보니 ballMove 함수 내의 값들이 숫자만 조금씩 바뀌니까

    함수 내의 바뀌는 값들만 배열에 넣어놓고,  object가 생성될 때 초기화값으로 지정해줘도 됐겠다란 생각이 든다.

     

    저 때는 보스공격패턴을 만들 때 이 방법이 가장 먼저 생각났고, 유레카하면서 신나게 코드를 작성했는데,

    과거의 나.. 부끄럽다 ..ㅋㅋㅋ

     

    그래도 덕분에 얻은 건 Reflection이라는 기능을 알게되었다는 것

    함수를 반복적으로 만들지 않았다면 호출하는 부분에서 코드를 줄이고자 하는 고민도 하지 못했을 테니까.

    reflection은 함수 외에도 클래스, 변수 등에서 다양하게 사용할 수 있다.

     

     

     

    참고문서

    docs.microsoft.com/ko-kr/dotnet/api/system.reflection?view=net-5.0

     

    System.Reflection 네임스페이스

    메타데이터를 검사하여 관리 코드에서 어셈블리, 모듈, 멤버, 매개 변수 및 기타 엔터티에 대한 정보를 검색하는 형식이 포함되어 있습니다. Contains types that retrieve information about assemblies, modules, m

    docs.microsoft.com

     

    '언어 > C#' 카테고리의 다른 글

    [C#] json 사용방법 + 유니티  (0) 2021.02.19
    [C#] List<T> 클래스 사용법  (0) 2020.10.29

    댓글

Designed by Tistory.