English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# 특성(Attribute)

특성(Attribute)은 실행 시간에 프로그램의 다양한 요소(예: 클래스, 메서드, 구조, 열거형, 컴포넌트 등)의 행위 정보를 전달하는 선언적 태그입니다. 특성을 사용하여 프로그램에 선언적 정보를 추가할 수 있습니다. 선언적 태그는 적용된 요소 앞에 배치된 괄호([ ])로 설명됩니다.

특성(Attribute)는 메타데이터를 추가하는 데 사용되며, 컴파일러 명령, 주석, 설명, 메서드, 클래스 등 다른 정보를 포함합니다. .Net 프레임워크는 두 가지 유형의 특성을 제공합니다:프리빌트특성과사용자 정의특성.

특성(Attribute)

특성(Attribute)의 문법은 다음과 같습니다:

[attribute(positional_parameters, name_parameter=value, ...)]
element

특성(Attribute)의 이름과 값은 괄호 내에 지정되며, 적용된 요소 앞에 배치됩니다. positional_parameters는 필수 정보를 지정하며, name_parameter는 선택 정보를 지정합니다.

프리빌트 특성(Attribute)

.Net 프레임워크는 세 가지 프리빌트 특성을 제공합니다:

  • AttributeUsage

  • Conditional

  • Obsoleted

AttributeUsage

프리빌트 특성 AttributeUsage 사용자 정의 특성 클래스를 사용하는 방법을 설명합니다. 이는 특성이 적용될 수 있는 프로젝트의 유형을 지정합니다.

이 특성의 문법은 다음과 같습니다:

[AttributeUsage(
   validon,
   AllowMultiple=allowmultiple,
   Inherited=inherited
)]

중에서:

  • validon 매개변수는 특성이 배치될 언어 요소를 지정합니다. 이는 엔럼버러입니다 AttributeTargets 의 값의 조합입니다. 기본 값은 AttributeTargets.All

  • 파라미터 입니다。옵션적) 이 특성의 allowmultiple AllowMultiple

  • 파라미터 속성(property)은 부울 값을 제공합니다. true라면, 이 특성은 다중 사용 가능합니다. 기본 값은 false(단일 사용).옵션적) 이 특성의 Inherited 속성(property)은 부울 값을 제공합니다. true라면, 이 특성은 상속 가능합니다. 기본 값은 false(상속되지 않음).

예를 들어:

[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property, 
AllowMultiple = true)

Conditional

이 предопределенная функция는 지정된 предобработчик로 실행이 의존하는 조건적 메서드를 표시합니다.

지정된 값에 따라 메서드 호출의 조건적 컴파일을 유발합니다. Debug 또는 Trace예를 들어, 디버깅 코드에서 변수의 값을 표시합니다.

이 특성의 문법은 다음과 같습니다:

[Conditional(
   conditionalSymbol
)]

예를 들어:

[Conditional("DEBUG")]

아래의 예제는 이 특성을 보여줍니다:

#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("Function 1.');
        function2();
    }
    static void function2()
    {
        Myclass.Message("Function 2.');
    }
    public static void Main()
    {
        Myclass.Message("Main function.");
        function1();
        Console.ReadKey();
    }
}

위 코드가 컴파일 및 실행될 때, 다음과 같은 결과가 발생합니다:

Main function
Function 1
Function 2

Obsoleted

이 предопределенная функция는 사용되지 않아야 하는 프로그램 요소를 표시합니다. 이는 컴파일러가 특정 목표 요소를 제거하도록 알릴 수 있게 합니다. 예를 들어, 새로운 메서드가 클래스에 사용되었지만, 여전히 클래스의 오래된 메서드를 유지하고 싶다면, 새로운 메서드를 사용하도록 알리는 메시지를 표시하여 obsolete(과거의)로 표시할 수 있습니다.

이 특성의 문법은 다음과 같습니다:

[Obsoleted(
   message
)]
[Obsoleted(
   message,
   iserror
)]

중에서:

  • 파라미터 message이는 프로젝트가 왜 오래된 것인지 설명하며, 대체 사용할 것을 지정하는 문자열입니다.

  • 파라미터 iserror이는 부울 값입니다. 이 값이 true라면, 컴파일러는 해당 요소의 사용을 오류로 처리해야 합니다. 기본 값은 false(컴파일러는 경고를 생성합니다).

아래의 예제는 이 특성을 보여줍니다:

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();
   }
}

이 프로그램을 컴파일하려고 시도할 때, 컴파일러는 다음과 같은 오류 메시지를 출력합니다:

 OldMethod를 사용하지 마세요, 대신 NewMethod를 사용하세요

사용자 정의 특성(Attribute) 생성

.Net 프레임워크는 선언적인 정보를 저장하고 실행 시간에 검색할 수 있는 사용자 정의 특성을 생성할 수 있게 합니다. 이 정보는 설계 표준과 애플리케이션 요구 사항에 따라 어떤 목표 요소와도 관련될 수 있습니다.

사용자 정의 특성을 생성하고 사용하는 것은 네 가지 단계로 이루어집니다:

  • 를 통해 선언되어야 합니다.

  • 의 사용자 정의 특성을 만들어 보겠습니다.

  • 목표 프로그램 요소에 사용자 정의 특성을 적용

  • 반영을 통해 특성에 접근

마지막 단계는 메타데이터를 읽어서 다양한 심볼을 찾기 위한 간단한 프로그램을 작성하는 것입니다. 메타데이터는 다른 데이터를 설명하는 데이터와 정보입니다. 이 프로그램은 반영(reflection)을 사용하여 실행 시간에 특성에 접근해야 합니다. 이 점은 다음 장에서 자세히 논의할 것입니다.

를 통해 선언되어야 합니다.

새로운 사용자 정의 특성은 System.Attribute 클래스를 선언했습니다. 예를 들어:

// 一个自定义特性 BugFix 被赋给类及其成员
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)
public class DeBugInfo : System.Attribute

위의 코드에서는 DeBugInfo 의 사용자 정의 특성.

의 사용자 정의 특성을 만들어 보겠습니다.

이름을 DeBugInfo 의 사용자 정의 특성이 있으며, 이는 디버거가 얻은 정보를 저장합니다. 이는 다음과 같은 정보를 저장합니다:

  • 버그의 코드 번호

  • 이 버그를 인식한 개발자 이름

  • 이 코드를 마지막으로 검토한 날짜

  • 개발자 표시를 저장한 문자열 메시지

우리의 DeBugInfo 클래스는 세 개의 개인적인 속성(property)을 가지고 있으며 이는 첫 세 가지 정보를 저장하고, 메시지를 저장하는 공개적인 속성(property)을 가지고 있습니다. 따라서 버그 번호, 개발자 이름, 검토 날짜는 DeBugInfo 클래스의 필수적인 위치(위치) 매개변수가 될 것이며, 메시지는 선택적인 이름된 매개변수가 될 것입니다.

모든 특성은 최소한 하나의 생성자가 필요합니다. 필수적인 위치(위치) 매개변수는 생성자를 통해 전달되어야 합니다. 아래의 코드는 이를 보여줍니다. DeBugInfo 类:

// 一个自定义特性 BugFix 被赋给类及其成员
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)
public class DeBugInfo : System.Attribute
{
  private int bugNo;
  private string developer;
  private string lastReview;
  public string message;
  public DeBugInfo(int bg, string dev, string d)
  {
      this.bugNo = bg;
      this.developer = dev;
      this.lastReview = d;
  }
  public int BugNo
  {
      get
      {
          return bugNo;
      }
  }
  public string Developer
  {
      get
      {
          return developer;
      }
  }
  public string LastReview
  {
      get
      {
          return lastReview;
      }
  }
  public string Message
  {
      get
      {
          return message;
      }
      set
      {
          message = value;
      }
  }
}

应用自定义特性

通过把特性放置在紧接着它的目标之前,来应用该特性:

[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;
  protected double 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("길이: {0}", length);
      Console.WriteLine("폭: {0}", width);
      Console.WriteLine("면적: {0}", GetArea());
  }
}

다음 장에서는 Reflection 클래스 객체를 사용하여 이 정보를 검색할 것입니다。