애트리뷰트는 코드에 대한 부가 정보를 기록하고 읽을 수 있는 기능이다.
애트리뷰트와 주석의 차이점
애트리뷰트를 이용해서 클래스나 구조체, 메소드, 프로퍼티 등에 데이터를 기록해두면 C# 컴파일러나 C#으로 작성된 프로그램이 이 정보를 읽고 사용할 수 있다.
[애트리뷰트_이름(애트리뷰트_매개변수)]
public void MyMethod()
{
}
using System;
namespace BasicAttribute
{
class MyClass
{
[Obsolete("OldMethod는 폐기되었습니다. NewMethod()를 이용하세요.")]
public void OldMethod()
{
Console.WriteLine("I'm old");
}
public void NewMethod()
{
Console.WriteLine("I'm new");
}
}
class MainApp
{
static void Main()
{
MyClass obj = new MyClass();
obj.OldMethod();
obj.NewMethod();
}
}
}
C# 5.0 버전부터 호출자 정보 애트리뷰트가 도입되었다.
호출자 정보는 메소드의 매개변수에 사용되며 메소드의 호출자 이름, 호출자 메소드가 정의된 소스 파일 경로, 소스 파일 내의 행번호까지 알 수 있다.
| 애트리뷰트 | 설명 |
|---|---|
| CallerMemberNameAttribute | 호출한 메소드 또는 프로퍼티의 이름을 나타낸다. |
| CallerFilePathAttribute | 호출된 소스 파일 경로를 나타낸다. 경로는 소스코드를 컴파일할 때의 전체 경로를 나타낸다. |
| CallerLinNumberAttribute | 호출된 소스 파일 내의 행 번호를 나타낸다. |
using System;
using System.Runtime.CompilerServices;
namespace CallerInfo
{
static class Trace
{
public static void WriteLine(string message,
[CallerFilePath] string file = "",
[CallerLineNumber] int line = 0,
[CallerMemberName] string member = "")
{
Console.WriteLine($"{file}(Line:{line} {member}: {message}");
}
}
class MainApp
{
static void Main()
{
Trace.WriteLine("즐거운 프로그래밍!");
}
}
}
모든 애트리뷰트는 System.Attribute 클래스로부터 상속을 받아 만들어진다.
class History : System.Attribute
{
//
}
[History]
class MyClass
{
//
}
System.AttributeUsage는 애트리뷰트의 애트리뷰트이다.
애트리뷰트가 어떤 대상을 설명할지, 중복해서 사용할 수 있는지의 여부 등을 설명한다.
[System.AttributeUsage(System.AttributeTargets.Class, AllowMutiple = true)]
class History : System.Attribute
{
//
}
System.AttributeUsage의 첫 번째 매개변수는 지금 선언하고 있는 애트리뷰트의 설명 대상이 무엇인지 나타낸다.
이것을 Attribute Target이라고 한다.
| Attribute Target | 설명 |
|---|---|
| All | 모든 요소 |
| Assembly | 어셈블리 |
| Module | 모듈 |
| Interface | 인터페이스 |
| Class | 클래스 |
| Struct | 구조체 |
| ClassMembers | 클래스 안에 선언된 클래스나 구조체를 포함한 클래스의 모든 멤버 |
| Constructor | 생성자 |
| Delegate | 대리자 |
| Enum | 열거형 |
| Event | 이벤트 |
| Field | 필드 |
| Property | 프로퍼티 |
| Method | 메소드 |
| Parameter | 메소드의 매개변수 |
| ReturnType | 메소드의 반환 값 |
Attribute Target은 논리합 연산자를 이용해 결합하여 사용할 수 있다.
System.AttributeUsage의 두 번째 매개변수는 여러 번 사용할 수 있도록 해준다.
using System;
namespace HistoryAttribute
{
[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)]
class History : System.Attribute
{
private string programmer;
public double version;
public string changes;
public History(string programmer)
{
this.programmer = programmer;
version = 1.0;
changes = "First Release";
}
public string GetProgrammer()
{
return programmer;
}
}
[History("JaeJun", version = 0.1, changes = "2022-02-15 Created Class Stub")]
[History("JaeJun", version = 0.2, changes = "2023-02-15 Added Func() Method")]
class MyClass
{
public void Func()
{
Console.WriteLine("Func()");
}
}
class MainApp
{
static void Main()
{
Type type = typeof(MyClass);
Attribute[] attributes = Attribute.GetCustomAttributes(type);
Console.WriteLine("MyClass change history...");
foreach (Attribute a in attributes)
{
History h = a as History;
if (h != null)
{
Console.WriteLine($"Ver:{h.version}, Programmer:{h.GetProgrammer()}, Changes:{h.changes}");
}
}
}
}
}