21. 코드에 부가 정보를 기록하는 어트리뷰트 (Attribute)

어트리뷰트(Attribute)란 코드에 대한 부가 정보를 기록하는 기능입니다. 주석만으로도 코드에 대한 설명을 작성할 수 있지만, 어트리뷰트는 컴퓨터가 읽기 위한 부가 정보입니다. 


예를 들어 여러분이 오픈소스 라이브러리를 만들었다고 가정해봅시다. 그런데 어떤 메소드에서 버그가 발견되어 그걸 대체하는 메소드를 만들었습니다. 하지만 기존에 라이브러리를 사용하던 사람들은 새로운 메소드가 나온지를 모릅니다. 여기서 어트리뷰트를 사용한다면 버그가 있는 메소드를 사용 시 경고를 내려줄 수 있습니다.


어트리뷰트는 설명하고자 하는 코드 앞에 [ ] 를 만들고 그 안에 어트리뷰트 이름을 기입하면 됩니다.


Code :

class Program
{
    [Obsolete("SafeMethod()를 사용해주세요!")]
    public void UnsafeMethod()
    {
        Console.WriteLine("안전하지 않은 메소드입니다.");
    }

    public void SafeMethod()
    {
        Console.WriteLine("안전한 메소드입니다.");
    }

    static void Main(string[] args)
    {
        // 경고만 내는 것이므로 출력은 됩니다.
        Program p = new Program();
        p.UnsafeMethod();
        p.SafeMethod();
    }
}

Result :

안전하지 않은 메소드입니다.

안전한 메소드입니다.

Obsolete 어트리뷰트는 .NET에서 기본적으로 제공하고 있는 대표적인 어트리뷰트입니다. 결과는 제대로 출력이 되지만 추가적으로 빌드 정보 출력창에 경고가 따라 뜹니다.


Obsolete 어트리뷰트 외에도 C나 C++로 작성된 DLL 파일을 참조하는 [DLLImport], 메소드를 조건부로 실행하는 [Conditional] 등 많은 어트리뷰트가 있습니다. 공부할 때 모든 어트리뷰트를 공부하면 좋지만 워낙 종류가 많기 때문에 필요할 때 필요한 것만 공부하면 됩니다.


또한 어트리뷰트는 사용자가 직접 만들수도 있는데, 이를 커스텀 어트리뷰트라 부릅니다.


Code :

class ReleaseLog : System.Attribute
{
    private string programmer;

    public string Version { get; set; }
    public string Changes { get; set; }
    public string Programmer { get; }

    // 생성자
    public ReleaseLog(string programmer)
    {
        this.programmer = programmer;
        Version = "1.0.0";
        Changes = "First Release";
    }
}

[ReleaseLog("xtasy", Version = "1.0.1", Changes = "없음")]
class Program { }

어트리뷰트는 System.Attribute 클래스를 상속받는 것만으로도 바로 어트리뷰트로서 사용이 가능해집니다. 추가하고 싶은 내용은 프로퍼티와 필드 등의 구현으로 만들면 됩니다.


그리고 보통 이렇게 만든 어트리뷰트는 이후 한 번 말고는 사용할 수가 없습니다. 따라서 다음 코드의 내용처럼 중복해서 사용하려면 System.AttributeUsage 어트리뷰트를 어트리뷰트화하는 대상 앞에 명시해줘야 합니다.


Code :

[System.AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class ReleaseLog : System.Attribute
{
    private string programmer;

    public string Version { get; set; }
    public string Changes { get; set; }
    public string Programmer { get; }

    // 생성자
    public ReleaseLog(string programmer)
    {
        this.programmer = programmer;
        Version = "1.0.0";
        Changes = "First Release";
    }
}

[ReleaseLog("xtasy", Version = "1.0.1", Changes = "없음")]
[ReleaseLog("test", Version = "1.0.2", Changes = "중복 적용")]
class Program { }

두 번째 매개변수는 대충 봐도 의미를 알 수 있지만, 첫 번째 매개변수는 약간의 설명이 필요합니다. 첫 번째 매개변수는 지금 선언하고 있는 어트리뷰트의 설명 대상이 무엇인지를 나타내는 값으로 어트리뷰트 타겟이라 부릅니다. 설명 대상을 가리키는 값으로는 Class 말고도 Method, Module 등이 있습니다.

Trackbacks 0 / Comments 0

Leave Comments