다음을 통해 공유


특성

특성은 메타데이터 또는 선언적 정보를 코드(어셈블리, 형식, 메서드, 속성 등)와 연결하는 강력한 방법을 제공합니다. 특성과 프로그램 엔터티를 연결한 후에는 리플렉션 기술을 사용하여 런타임에 특성을 쿼리할 수 있습니다.

특성에는 다음과 같은 속성이 있습니다.

  • 특성은 프로그램에 메타데이터를 추가합니다. 메타데이터 프로그램에 정의된 형식에 대한 정보입니다. 모든 .NET 어셈블리에는 어셈블리에 정의된 형식 및 형식 멤버를 설명하는 지정된 메타데이터 집합이 포함되어 있습니다. 사용자 지정 특성을 추가하여 다른 필수 정보를 지정할 수 있습니다.
  • 특성은 전체 어셈블리, 모듈 또는 클래스 및 속성과 같은 더 작은 프로그램 요소에 적용할 수 있습니다.
  • 특성은 메서드 및 속성과 동일한 방식으로 인수를 수락할 수 있습니다.
  • 특성을 사용하면 프로그램이 리플렉션을 사용하여 다른 프로그램에서 자체 메타데이터 또는 메타데이터를 검사할 수 있습니다.

반성 작업

Type 제공하는 리플렉션 API는 어셈블리, 모듈 및 형식을 설명합니다. 리플렉션을 사용하여 형식의 인스턴스를 동적으로 만들거나, 형식을 기존 개체에 바인딩하거나, 기존 개체에서 형식을 가져와 해당 메서드를 호출하거나 해당 필드 및 속성에 액세스할 수 있습니다. 코드에서 특성을 사용하면 리플렉션을 통해 특성에 액세스할 수 있습니다. 자세한 내용은 특성참조하세요.

다음은 GetType() 메서드를 사용한 간단한 리플렉션 예제입니다. Object 기본 클래스의 모든 형식은 변수 형식을 가져오는 데 사용되는 이 메서드를 상속합니다.

메모

C#(.cs) 코드 파일의 맨 위에 using System;using System.Reflection; 문을 추가해야 합니다.

// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

출력에는 다음 형식이 표시됩니다.

System.Int32

다음 예제에서는 리플렉션을 사용하여 로드된 어셈블리의 전체 이름을 가져옵니다.

// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

출력은 다음 예제와 유사합니다.

System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

IL의 키워드 차이점

C# 키워드 protectedinternal IL(중간 언어)에는 의미가 없으며 리플렉션 API에 사용되지 않습니다. IL의 해당 용어는 Family어셈블리. 다음 몇 가지 방법으로 다음 용어를 사용할 수 있습니다.

  • 리플렉션을 사용하여 internal 메서드를 식별하려면 IsAssembly 속성을 사용합니다.
  • protected internal 메서드를 식별하려면 IsFamilyOrAssembly사용합니다.

속성 작업하기

특성은 거의 모든 선언에 배치할 수 있지만 특정 특성은 유효한 선언 형식을 제한할 수 있습니다. C#에서는 적용되는 엔터티 선언 위에 대괄호([])로 묶인 특성의 이름을 배치하여 특성을 지정합니다.

이 예제에서는 SerializableAttribute 특성을 사용하여 클래스에 특정 특성을 적용합니다.

[Serializable]
public class SampleClass
{
    // Objects of this type can be serialized.
}

DllImportAttribute 특성을 사용하여 메서드를 선언할 수 있습니다.

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

선언에 여러 특성을 배치할 수 있습니다.

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

일부 특성은 지정된 엔터티에 대해 두 번 이상 지정할 수 있습니다. 다음 예제에서는 ConditionalAttribute 특성의 여러 가지 사용 방법을 보여줍니다.

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
    // ...
}

메모

규칙에 따라 모든 특성 이름은 접미사 "특성"으로 끝나 .NET 라이브러리의 다른 형식과 구분됩니다. 그러나 코드에서 특성을 사용할 때는 특성 접미사를 지정할 필요가 없습니다. 예를 들어 [DllImport] 선언은 [DllImportAttribute] 선언과 동일하지만 DllImportAttribute .NET 클래스 라이브러리에 있는 클래스의 실제 이름입니다.

특성 매개 변수

많은 특성에는 위치 매개 변수 , 이름 없는 매개 변수 , 또는 명명된 매개 변수 가 있습니다. 다음 표에서는 이름이 지정되고 위치가 지정된 특성을 사용하는 방법을 설명합니다.

위치 매개 변수

특성 생성자의 매개 변수:

명명된 매개 변수

특성의 속성 또는 필드:

  • 지정해야 합니다. 생략할 수 없습니다.
  • 항상 먼저 지정
  • 을 특정 순서로 지정
  • 항상 선택 사항, false인 경우 생략
  • 위치 매개 변수 뒤 지정
  • 순서대로 지정

예를 들어 다음 코드는 다음과 같은 세 가지 동일한 DllImport 특성을 보여줍니다.

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

첫 번째 매개 변수인 DLL 이름은 위치이며 항상 먼저 제공됩니다. 다른 인스턴스는 명명된 매개 변수입니다. 이 시나리오에서는 명명된 매개 변수를 모두 false로 기본 설정하므로 생략할 수 있습니다. 기본 매개 변수 값에 대한 자세한 내용은 개별 특성 설명서를 참조하세요. 허용되는 매개 변수 형식에 대한 자세한 내용은 C# 언어 사양특성 섹션을 참조하세요.

특성 대상

특성의 대상은 특성이 적용되는 엔터티입니다. 예를 들어 특성은 클래스, 메서드 또는 어셈블리에 적용할 수 있습니다. 기본적으로 특성은 뒤에 있는 요소에 적용됩니다. 그러나 메서드, 매개 변수 또는 반환 값과 같이 연결할 요소를 명시적으로 식별할 수도 있습니다.

특성 대상을 명시적으로 식별하려면 다음 구문을 사용합니다.

[target : attribute-list]

다음 표에는 가능한 target 값 목록이 나와 있습니다.

대상 값 적용 대상
assembly 전체 조립체
module 현재 어셈블리 모듈
field 클래스 또는 구조체의 필드
event 이벤트
method 메서드 또는 getset 속성 접근자
param 메서드 매개 변수 또는 set 속성 접근자 매개 변수
property 재산
return 메서드, 속성 인덱서 또는 get 속성 접근자의 반환값
type 구조체, 클래스, 인터페이스, 열거형 또는 대리자

field 대상 값을 지정하여 에 자동으로 구현된 속성에 대해 만든 지원 필드에 특성을 적용할 수 있습니다.

다음 예제에서는 어셈블리 및 모듈에 특성을 적용하는 방법을 보여 줍니다. 자세한 내용은 공통 특성(C#)참조하세요.

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

다음 예제에서는 C#의 메서드, 메서드 매개 변수 및 메서드 반환 값에 특성을 적용하는 방법을 보여 줍니다.

// default: applies to method
[ValidatedContract]
int Method1() { return 0; }

// applies to method
[method: ValidatedContract]
int Method2() { return 0; }

// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }

// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

메모

ValidatedContract 특성이 유효한 것으로 정의된 대상에 관계없이 ValidatedContract 특성이 반환 값에만 적용되도록 정의된 경우에도 return 대상을 지정해야 합니다. 즉, 컴파일러는 AttributeUsage 정보를 사용하여 모호한 특성 대상을 해결하지 않습니다. 자세한 내용은 AttributeUsage참조하세요.

특성을 사용하는 방법 검토

코드에서 특성을 사용하는 몇 가지 일반적인 방법은 다음과 같습니다.

  • HttpPost 특성을 사용하여 POST 메시지에 응답하는 컨트롤러 메서드를 표시합니다. 자세한 내용은 HttpPostAttribute 클래스를 참조하세요.
  • 네이티브 코드와 상호 운용할 때 메서드 매개 변수를 마샬링하는 방법을 설명합니다. 정보는 MarshalAsAttribute 클래스를 참조하세요.
  • 클래스, 메서드 및 인터페이스에 대한 COM(구성 요소 개체 모델) 속성을 설명합니다.
  • DllImportAttribute 클래스를 사용하여 관리되지 않는 코드를 호출합니다.
  • 타이틀, 버전, 설명 또는 상표 측면에서 어셈블리를 설명합니다.
  • 지속성을 위해 serialize할 클래스의 멤버를 설명합니다.
  • XML serialization을 위해 클래스 멤버와 XML 노드 간에 매핑하는 방법을 설명합니다.
  • 메서드에 대한 보안 요구 사항을 설명합니다.
  • 보안을 적용하는 데 사용되는 특성을 지정합니다.
  • 코드를 디버그하기 쉽게 유지하도록 JIT(Just-In-Time) 컴파일러를 사용하여 최적화를 제어합니다.
  • 메서드 호출자에 대한 정보를 가져옵니다.

리플렉션 시나리오 검토

리플렉션은 다음 시나리오에서 유용합니다.

  • 프로그램 메타데이터의 특성에 액세스합니다. 자세한 내용은 특성에 저장된 정보 검색을 참조하세요.
  • 어셈블리에서 형식을 검사하고 인스턴스화합니다.
  • System.Reflection.Emit 네임스페이스의 클래스를 사용하여 런타임에 새 형식을 빌드합니다.
  • 런타임에 생성된 형식에 대해 지연 바인딩을 수행하고 메서드에 접근합니다. 자세한 내용은 형식을 동적으로 로드하고 사용하는참조하세요.