산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C# 어트리뷰트(Attribute) 마스터하기: 메타데이터로 코드 강화하기

어트리뷰트(Attribute)는 클래스, 메서드, 구조체, 열거자, 어셈블리 등 프로그램 요소의 동작에 대한 정보를 런타임에 전달하는 선언적 태그(Declarative Tag)입니다. 대괄호 [ ] 안에 요소 위에 배치하여 사용합니다.

어트리뷰트는 컴파일러 지시사항, 설명, 메서드/클래스 정보 등 메타데이터(Metadata)를 프로그램에 추가하는 데 사용됩니다. .NET Framework는 미리 정의된(Predefined) 어트리뷰트와 사용자 정의(Custom) 어트리뷰트 두 가지를 제공합니다.

어트리뷰트 지정 구문

[어트리뷰트(위치_매개변수, 이름_매개변수 = 값, ...)] 대상_요소

미리 정의된 어트리뷰트 (Predefined Attributes)

.NET Framework가 제공하는 세 가지 핵심 미리 정의 어트리뷰트:

1. AttributeUsage

사용자 정의 어트리뷰트 클래스가 어떻게 사용될 수 있는지 설명합니다. 적용 가능한 언어 요소 타입 지정.

[AttributeUsage(
    validOn,                    // 적용 대상 (AttributeTargets 열거자 조합)
    AllowMultiple = bool,       // 다중 적용 허용 여부 (기본 false)
    Inherited = bool            // 파생 클래스에 상속 여부 (기본 false)
)]

validOn의 주요 AttributeTargets 값: All, Class, Struct, Method, Property, Field, Constructor, Parameter, Assembly, Module, Interface, Enum, Delegate, ReturnValue, GenericParameter 등.

예제

[AttributeUsage(
    AttributeTargets.Class | 
    AttributeTargets.Constructor | 
    AttributeTargets.Field | 
    AttributeTargets.Method | 
    AttributeTargets.Property,
    AllowMultiple = true
)]
public class MyCustomAttribute : Attribute { }

2. Conditional

지정된 전처리 심볼에 따라 메서드 호출을 조건부 컴파일합니다. 주로 DEBUG나 TRACE 심볼과 함께 디버깅용 메서드에 사용.

[Conditional("심볼_이름")]

예제

#define DEBUG
using System;
using System.Diagnostics;

public class MyClass
{
    [Conditional("DEBUG")]
    public static void Message(string msg)
    {
        Console.WriteLine(msg);
    }
}

class Test
{
    static void Function1()
    {
        MyClass.Message("In Function 1.");
        Function2();
    }
    
    static void Function2()
    {
        MyClass.Message("In Function 2.");
    }
    
    public static void Main()
    {
        MyClass.Message("In Main function.");
        Function1();
        Console.ReadKey();
    }
}

출력 (DEBUG 정의 시): In Main function / In Function 1 / In Function 2

출력 (DEBUG 미정의 시): (아무 출력 없음 - 메서드 호출 자체가 컴파일에서 제거됨)

핵심: Conditional 메서드는 void 반환 타입만 가능하며, 인터페이스 메서드나 오버라이드 메서드에는 적용 불가.

3. Obsolete

사용하지 말아야 할 프로그램 요소에 표시. 컴파일러가 경고 또는 에러 발생.

[Obsolete("메시지")]
[Obsolete("메시지", isError)]

예제

using System;

public class MyClass
{
    [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
    static void OldMethod()
    {
        Console.WriteLine("It is the old method");
    }
    
    static void NewMethod()
    {
        Console.WriteLine("It is the new method");
    }
    
    public static void Main()
    {
        OldMethod();  // 컴파일 에러 발생
    }
}

컴파일 에러: Don't use OldMethod, use NewMethod instead

사용자 정의 어트리뷰트 (Custom Attributes) 만들기

.NET Framework는 선언적 정보를 저장하고 런타임에 검색할 수 있는 사용자 정의 어트리뷰트 생성을 허용합니다.

4단계 과정

  1. 사용자 정의 어트리뷰트 선언
  2. 사용자 정의 어트리뷰트 생성자 구현
  3. 대상 프로그램 요소에 어트리뷰트 적용
  4. 리플렉션(Reflection)으로 런타임에 어트리뷰트 접근

1단계: 선언

System.Attribute 클래스에서 파생.

[AttributeUsage(
    AttributeTargets.Class | 
    AttributeTargets.Constructor | 
    AttributeTargets.Field | 
    AttributeTargets.Method | 
    AttributeTargets.Property,
    AllowMultiple = true
)]
public class DeBugInfo : System.Attribute { }

2단계: 생성자 및 속성 구현

public class DeBugInfo : System.Attribute
{
    private int bugNo;
    private string developer;
    private string lastReview;
    public string Message { get; set; }  // 명명된 매개변수
    
    // 위치 매개변수 (생성자 필수)
    public DeBugInfo(int bg, string dev, string d)
    {
        bugNo = bg;
        developer = dev;
        lastReview = d;
    }
    
    public int BugNo => bugNo;
    public string Developer => developer;
    public string LastReview => lastReview;
}

3단계: 적용

[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle
{
    protected double length, width;
    
    public Rectangle(double l, double w) { length = l; width = w; }
    
    [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
    public double GetArea() { return length * width; }
    
    [DeBugInfo(56, "Zara Ali", "19/10/2012")]
    public void Display()
    {
        Console.WriteLine("Length: {0}", length);
        Console.WriteLine("Width: {0}", width);
        Console.WriteLine("Area: {0}", GetArea());
    }
}

4단계: 리플렉션으로 읽기 (다음 장에서 상세)

Type type = typeof(Rectangle);
foreach (object attr in type.GetCustomAttributes(false))
{
    DeBugInfo dbi = (DeBugInfo)attr;
    Console.WriteLine($"Bug: {dbi.BugNo}, Dev: {dbi.Developer}, Review: {dbi.LastReview}, Msg: {dbi.Message}");
}

자주 쓰는 내장 어트리뷰트

어트리뷰트용도
[Serializable]직렬화 가능 표시
[NonSerialized]필드 직렬화 제외
[DllImport]비관리 DLL 함수 임포트
[AttributeUsage]커스텀 어트리뷰트 사용 규칙 정의
[Conditional]조건부 메서드 컴파일
[Obsolete]사용 중단 경고/에러
[CallerMemberName]호출자 멤버 이름 자동 전달 (C# 5.0+)
[CallerFilePath]호출자 파일 경로 자동 전달
[CallerLineNumber]호출자 줄 번호 자동 전달
모범 사례: 어트리뷰트는 메타데이터용으로만 사용하고, 비즈니스 로직에는 사용하지 마세요. 리플렉션으로 읽을 때 성능 비용이 있으므로 자주 접근하는 경로에서는 캐싱을 고려하세요.

C 언어

  1. Java 8 Optional 마스터하기: 널-안전 코드를 위한 실용 가이드
  2. C# 널 허용 타입(Nullable Types) 완벽 이해: 안전한 null 처리
  3. Ferro-Titanit® Cromoni – 고강도 비자성 티타늄 합금
  4. AgCu20 합금: 23°C에서 종합적인 기계적 및 열적 특성
  5. 합금 15CDV6 (DIN 1.7734) – 고강도·인성·용이한 용접성
  6. DIN 1.7734 15CDV6 합금 – 고강도·인성·용이한 용접성 (고강도 열처리품)
  7. 15CDV6 합금 (DIN 1.7734) – 초고강도·용이한 용접·우수 인성 (최고 강도 열처리품)
  8. PtNi10 합금: 종합적인 기계적 및 열적 특성
  9. PtIr10 백금-이리듐 합금: 고강도 고온 소재
  10. Corroplast 플레이트 – 정밀 가공용 고성능 내식 강재