확장 메서드는 C#의 강력한 기능 중 하나로, 내가 소스 코드를 직접 수정할 수 없는 클래스에 마치 인스턴스 메서드처럼 새 메서드를 추가할 수 있게 해준다.
예를 들어 유니티에서 Transform, GameObject, Vector3 같은 유니티 엔진 내부 클래스나 외부 라이브러리에서 가져온 클래스를 내 입맛대로 확장할 수 있다.
기본형태
public static class ExtensionClassName
{
public static 반환형 메서드이름(this 확장할타입 인스턴스, [추가 파라미터])
{
// 메서드 내용
}
}
public static class TransformExtensions
{
public static void DestroyAllChildren(this Transform t)
{
for (int i = t.childCount - 1; i >= 0; i--)
{
Object.Destroy(t.GetChild(i).gameObject);
}
}
}
public static class TransformExtensions
{
public static void ResetPosition(this Transform t)
{
t.position = Vector3.zero;
}
}
transform.ResetPosition(); // position을 (0,0,0)으로 리셋
public static class GameObjectExtensions
{
public static void SetActiveSafe(this GameObject go, bool active)
{
if (go != null && go.activeSelf != active)
go.SetActive(active);
}
}
NRE(NullReferenceException) 예방, 이미 같은 상태일 땐 쓸데없는 호출 안 함
public static class Vector3Extensions
{
public static Vector3 WithY(this Vector3 v, float y)
{
return new Vector3(v.x, y, v.z);
}
}
transform.position = transform.position.WithY(10f);
public static class ListExtensions
{
public static void Shuffle<T>(this IList<T> list)
{
System.Random rand = new System.Random();
int n = list.Count;
while (n > 1)
{
int k = rand.Next(n--);
T temp = list[n];
list[n] = list[k];
list[k] = temp;
}
}
}
public static class ObjectExtensions
{
public static bool IsNull(this Object obj, string objName = "")
{
if (obj == null)
{
Debug.LogWarning($"{objName} is null!");
return true;
}
return false;
}
}
if (targetObj.IsNull("타겟 오브젝트")) return;
가독성, 유지보수성
코드 재사용
클린 코드
네임스페이스 관리
private/protected 멤버 접근 불가
오버로드/이름 충돌 주의
유니티에서 확장 메서드는 자주 사용되는 불편한 코드를 대상으로 엄청나게 다양한 곳에서 사용할 수 있다. 그로 인해 가독성이 좋아져 생산성도 좋아지고 리팩토링도 편해진다.
그렇지만 개인 작업이 아닌 협업이라면 의사소통 문제가 생길 수도 있고 같이 작업하는 팀원의 실력에 따라 생각보다 다양한 문제점이 생길 가능성도 분명히 존재하는것 같다.
개발자의 실력에 따라 가독성이 좋자고 만든 확장매서드가 오히려 코드를 더럽힐 가능성도 충분하니 주의하면서 사용하는게 좋아보인다.