카테고리 없음

Attribute

Cadi 2026. 3. 26. 17:29

목차

     

     

     

    1. Attribute란 ? 

     

    Attribute에 대해 알기 위해선 우선 '메타 데이터'라는 개념에 대해 알아야 한다. 

    메타데이터란 '데이터를 설명하는 데이터'를 뜻한다. 우리가 스마트폰으로 사진을 찍으면 사진(이미지 데이터) 파일 안에 촬영 날짜, 위치, 카메라 기종 같은 정보가 몰래 숨어있는데, 이것이 바로 메타데이터다.

     

    C# 프로그래밍에서는 코드를 컴파일 할 때, 클래스명은 무엇인지, 어떤 변수와 함수를 가졌는지 등의 구조 정보를 전부 모아서 DLL 파일 안에 기록해둔다. 전 포스팅에서 다뤘던 'Type(설계도)' 정보 자체가 C# 프로그래밍의 가장 기본적인 메타데이터인  것이다. 

     

    Attribute

    Attribute는 이렇게 기본적으로 생성되는 메타데이터 이외에 개발자가 추가로 붙이는 포스트잇이라고 생각하면 편하다. 
    설계도 자체나 , 특정 부품 (변수 / 함수 ) 앞에 "이렇게 다뤄주세요"라고 메모를 남기는 것이다. 

     

    Attribute의 가장 중요한 특성은 수동성이다. 포스트잇이라고 말한 것에서 알 수 있듯이, 이를 붙인다고 하여 클래스나 함수의 본래 기능이나 로직 자체가 변하지는 않는다. 오직 누군가 읽고 참고하라고 남겨두는 것이다. 

     

     

    2. Attribute는 어떻게 저장되어 있는가 ? 

    프로그램이 실행될 때 어트리뷰트는 자동으로 객체로 메모리에 올라가지 않는다. 컴파일러가 코드를 번역할 때, "여기에 포스트잇이 붙어 있음"이라는 텍스트 형태의 메타데이터로 변환되어 파일(DLL) 안에 기록될 뿐이다. 나중에 리플렉션(Reflection)을 통해 "포스트잇에 뭐라고 적혀 있는지 확인해봐!"라고 요청하는 순간에만 비로소 메모리에 객체(Instance)로 생성되어 우리에게 정보를 전달해 준다. 그 전까지는 하드디스크 속의 정적인 텍스트 데이터일 뿐이다.

     

     

    3. 자주 쓰는 Attribute들

     

    • [SerializeField] : 유니티 에디터에게 내리는 명령. "이 변수는 private이라 외부에서 못 보지만, 유니티 인스펙터 창에서는 예외적으로 값을 수정할 수 있게 노출해 줘!"
    • [RequireComponent(typeof(Rigidbody))] : 유니티 에디터와 런타임에 보내는 경고. "이 스크립트를 게임 오브젝트에 붙이려면 무조건 Rigidbody가 필요해! 없으면 네가 알아서 추가해 줘."
    • [Obsolete("이 함수는 구버전입니다.")] : C# 컴파일러와 동료 개발자에게 남기는 메모. "이 함수는 더 이상 쓰지 마. 쓰면 컴파일 창에 노란색 경고(Warning)를 띄울 거야."
    • [Header("Player Stats")], [Space] : 유니티 인스펙터 창의 UI를 예쁘게 꾸며달라고 에디터에게 요청하는 장식용 포스트잇.

     

    4. CustomAttribute

    기본적으로 제공되는 Attribute 이외에도 Attirbute를 만들 수 있다.

    System.Attribute 클래스를 상속받기만 하면 만들어진다. 

    using System;
    
    // 관례적으로 이름 끝에 'Attribute'를 붙인다.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class InteractableAttribute : Attribute
    {
        public string Description;
    
        // 생성자
        public InteractableAttribute(string desc)
        {
            Description = desc;
        }
    }

     

     

    위에서 사용한 AttributeUsage는 "어디에 붙일 수 있는지" 에 관한 것이다.
    예를 들어 위와 같이 (AttributeTargets.Class | AttributeTargets.Method) 라고 사용했다면 클래스와 함수에만 붙일 수 있다. 

    그리고 만들고 사용할 때 주의 사항은 다음과 같다.
    1. 관례적으로 이름 끝에 Attribute를 붙인다.

    // 어트리뷰트 정의
    public class InteractableAttribute : Attribute
    {
        // 생성자로 받는 필수 값
        public string Description; 
        
        // 선택적으로 넣을 수 있는 public 필드 (또는 프로퍼티)
        public int Priority = 0; 
        public bool IsOneTimeUse = false;
    
        public InteractableAttribute(string desc)
        {
            Description = desc;
        }
    }
    
    // 어트리뷰트 사용
    // 1. 필수 값만 넣기
    [Interactable("평범한 문")]
    public class NormalDoor { }
    
    // 2. 필수 값 + 프로퍼티(선택적 값) 함께 넣기
    [Interactable("황금 보물상자", Priority = 99, IsOneTimeUse = true)]
    public class GoldenBox { }

    2. 사용할 때에는 Attribute를 붙이지 않고 사용할 수 있다. ( EX: [Interactable("설명")]
    3. 매개변수가 있는 생성자를 갖고 있는 Attribute일 때에는 매개변수를 넣어준다. ( EX: [Interactable("설명") )
    4. 커스텀 어트리뷰트 클래스 안에 public으로 열려있는 변수(필드)나 프로퍼티가 있다면, 필수 값을 먼저 넣은 뒤에 이름 = 값 형태로 추가적인 데이터를 쏙쏙 골라서 넣을 수 있다. (순서 상관없음)  

     

     

    https://learn.microsoft.com/ko-kr/dotnet/csharp/advanced-topics/reflection-and-attributes/attribute-tutorial

     

    자습서: 사용자 지정 특성을 정의하고 읽습니다. - C#

    C#에서 특성이 작동하는 방식을 알아봅니다. 사용자 지정 특성을 정의하여 코드에 메타데이터를 추가합니다. 이러한 특성을 읽고 런타임 시 코드에 대해 알아봅니다.

    learn.microsoft.com

    * 이러한 Attribute 개체는 지연 초기화된다는 점에 유의해야 합니다. 즉, GetCustomAttribute 또는 GetCustomAttributes를 사용할 때까지 인스턴스화되지 않습니다. 또한 매번 인스턴스화됩니다. 행에서 두 번 호출 GetCustomAttributes 하면 두 개의 서로 다른 인스턴스가 반환됩니다 ObsoleteAttribute. 라는 문장이 있다. 

     

    공부하면서 적은 내용이기 때문에 틀릴 수 있습니다.