일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 델리게이트
- callbyvalue
- 게임개발
- 인터페이스
- 레이캐스트
- 게임제작
- C#
- 확장메서드
- ARProgect
- AR세팅
- 리듬게임에디터
- 소규모프로젝트
- 게임
- 로케트
- Unity
- ar
- Quaternion
- 1인개발
- ExtensionMethod
- github
- Euler
- raycast
- 깃허브
- AR게임
- AR Foundation
- 리듬게임
- 병맛게임
- callbyreference
- 짐벌락
- 유니티
- Today
- Total
Ssssong += Dev
[유니티, C#] 리플렉션(Reflection) 본문
타입의 결정을 런타임 시점으로 미뤄둘 수 있는 패턴이다.
컴파일 시점에서 위에 더 생길 클래스를 알지 못할 때 사용한다. 타입에 대한 정보를 가져와서 이후 처리한다.
GetType()은 단순히 데이터타입만을 의미하는 것이 아니라 해당 데이터타입이 가지고 있는 정보를 의미한다.
Temp temp로 생성된 객체를 temp.GetType() 으로 정보를 가져온다면 Temp가 가진 멤버도 가져올 수 있다.
FieldInfo[] fields = type.GetFields()로 해당 데이터타입이 가진 멤버 변수들을 가져올 수 있다.
BindingFlag를 사용하면 가져오는 멤버 변수의 성격 또한 지정할 수 있다.
Type type = slime.GetType();
type.GetField("hp").GetValue(slime);
위 코드는 slime의 hp를 가져온다. type은 slime의 데이터타입 자체를 담고 있기 때문에 slime 자체의 정보는 담고 있지 않다.
따라서 'slime의 타입으로 slime의 정보를 불러오겠다.' 라는 의미로 .GetValue(slime)을 해 주어야 한다.
GetValue과 반대로 SetValue는 값을 세팅한다.
type.GetField("hp").SetValue(slime, 80); 이런 형식으로 정보를 담는다.
단, 여기서 GetField("hp")의 형식이 어떻게 될 지 모르므로 이렇게 80으로 바로 적는 데에는 문제가 있다.
type.GetMethod("Attack").Invoke(slime, null);
데이터타입이 가진 함수를 가져온다. Invoke(객체, 매개변수)로 실행할 수 있다.
매개 변수가 없을 때에는 null을 넣으면 되지만 매개변수가 있을 때 매개변수의 갯수를 알 수 없다면 어떻게 해야 하는가?
이런 상황을 위해 매개변수를 object 배열로 넣어준다.
object[] args = new object[2];
args[0] = 10;
args[1] = 3;
type.GetMethod("Attack").Invoke(slime, args);
*parameter : 매개변수, argument : 실제로 들어가는 인자
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System;
public class Temp
{
public int tempValue;
public int TempValue
{
get { return tempValue; }
set { tempValue = value; }
}
public void FuncParamater()
{
Debug.Log("어떠한 기능");
}
}
public class Reflection : MonoBehaviour
{
private void Start()
{
Temp temp = new Temp();
temp.tempValue = 10;
Debug.Log("타입의 이름 : " + temp.GetType().Name);
Type type = temp.GetType(); // temp의 데이터타입 그 자체. temp의 정보는 없음
//type.GetFields 멤버 변수 가져옴
//type.GetPropertys 멤버 프로퍼티 가져옴
MethodInfo[] methods = type.GetMethods(); //멤버 함수 가져옴
int count = 0;
foreach(var method in methods)
{
Debug.Log(count + "번째의 메서드의 이름 : " + method.Name);
count++;
}
Debug.Log(type.GetField("tempValue").GetValue(temp)); //type이 데이터타입 그 자체이므로 temp 값을 알려면 temp를 다시 넣어줘야 한다.
type.GetField("tempValue").SetValue(temp,30);
type.GetMethod("FuncParamater").Invoke(temp, null); //null 자리에 매개변수 넣어야 할 경우 매개변수 들어감. 지금은 void라 null이 들어갔다.
}
}
리플렉션에 더해 DeepCopy 간소화 코드(예외 경우 많이 생략됨)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System;
public static class ExtensionMethod
{
public static T DeepCopy<T>(this T obj) where T : new()
{
Type type = obj.GetType();
if(type.IsClass)
{
T clone = new T();
//클래스 멤버들 가져오기
FieldInfo[] fields = type.GetFields();
//멤버마다 복사
foreach(FieldInfo field in fields)
{
field.SetValue(clone, (field.GetValue(obj)).DeepCopy());
}
return (T)clone;
}
//멤버가 복사가 되어야 하는 내용
return (T)obj;
}
}
'개발 > 공부' 카테고리의 다른 글
[C#] 커맨드 패턴 (Command Pattern), 퍼사드 패턴(Facade Pattern) (0) | 2022.06.24 |
---|---|
[유니티, C#] 반복자 패턴(Iterator Pattern), 코루틴 심화 (0) | 2022.06.23 |
[디자인패턴/C#] 옵저버 패턴, 템플릿 메서드 (0) | 2022.06.21 |
[C#] EventHandler (0) | 2022.06.21 |
[디자인패턴/C#] 전략 디자인패턴 (0) | 2022.06.20 |