닷넷 c# 어트리뷰트, Attribute는 클래스안에 메타정보를 포함 시킬 수 있는 기술로서 클래스, 데이터 구조, 열거자 그리고 어셈블리와 같은 프로그래밍적 요소들의 실행 시 행동에 대한 정보를 기술 할 수 있다.
다음과 같은 프로그래밍 요소에 대해 어트리뷰트를 사용 할 수 있다.
어셈블리, 모듈, 클래스, 구조체, 열거형 변수, 생성자, 메소드, 프로퍼티, 필드, 이벤트, 인터페이스, 파라미터, 반환 값, 델리게이트
어트리뷰트 역시 클래스의 일종이다.
어트리뷰트의 문법은 다음과 같다.
[attribute(positional_parameter, name_parameter = value, …) ]
파라미터에는 두 종류가 있는데 하나는 위치지정 파라미터로 반드시 들어와야 한다. 명명파라미터(name_parameter)는 꼭 필요하지는 않은 구조를 가지면 어트리뷰트 안에 추가적인 정보를 넣을 때 이용한다.
예를들면
[AdditionalInfo(“2011-01-01”)]
public class Test { ..}
원하는 프로그래밍 요소 위에 Attribute를 써주면 그곳에 Attribute가 배정되는 것이다.
1. Conditional Attribute
C# 디버깅을 지원하기 위해 Conditional Attribute를 사용 할 수 있다. Conditional Attribute는 사용자가 정의 한 값에 의해서 해당 메소드를 실행 하도록 한다.
#define SOUNDCARD // 이 부분을 지운 후 실행 해 보자
using System;
using System.Diagnostics;
class Test
{
//Conditional Attribute인 경우 지정된 위치지정 파라미터가 정의 되어
//있을 때 실행이 되는 것이다.
[Conditional ("SOUNDCARD")]
static void print()
{
Console.WriteLine("도레미...");
}
static void :namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Main ()
{
print();
}
}
Conditional Attribute는 클래스나 구조체 안에 있는 메소드 에서만 사용 할 수 있다. 또 그 메소드는 void 형 이어야 한다. 다음의 예문처럼 메소드에 대해 여러 Conditional Attribute를 붙이게 되면 그 중 하나만 위치지정 파라미터가 정의 되어 있어도 그 메소드를 실행 시킨다.
만약 두개의 Conditional Attribute를 모두 만족해야 메소드를 실행 할려면 아래와 같은 방법을 이용하면 된다.
[Conditional(“MODEM”), Conditional(“ADSL”)]
static void print() { .. }
#define SOUNDCARD
#define SPEAKER
using System;
using System.Diagnostics;
class Test
{
[Conditional ("SOUNDCARD")]
static void isSound()
{
isSpeaker();
}
[Conditional ("SPEAKER")]
static void isSpeaker()
{
Console.WriteLine("음악을 들을 수 있습니다...");
}
static void Main ()
{
isSound();
}
}
2. DllImport 어트리뷰트
DllImport Attribute는 C#안에서 Unmanaged Code를 사용 할 수 있게 한다. Unmanaged Code란 닷넷 환경 밖에서 개발된 코드를 가리킨다. DllImport Attribute는 System.Runtime.InteropServices 네임스페이스 안에 정의 되어 있다. 사용방법은 위치지정 파라미터로 사용 할 DLL 파일을 인자로 넘겨 주면 된다.
using System;
using System.Runtime.InteropServices;
class Test
{
//User32.dll 파일안의 MessageBox 함수를 불러와서 사용하는 예이다. DllImport Attribute를
//이용하여 사용할 코드가 포함되어 있는 DLL을 넘겨주고 extern키워드를 통해 사용하려고 하는
//메소드가 외부에 있음을 알린다. 이렇게 하면 닷넷 환경 밖에서 개발된 코드들도 C#안에서 쓸 수 있다.
[DllImport("User32.Dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static void Main ()
{
MessageBox(0, "Hello!", "In C#", 0);
}
}
3. Custom Attribute의 정의
- 어트리뷰트의 범위 지정
앞에서 Conditional Attribte는 메소드에만 붙일 수 있다고 했다. 그렇다면 사용자가 만든 어트리뷰트에 대해 어떤 곳에서만 붙일 수 있게 하는 방법은 없을까? AttributeUsage를 이용해서 사용자가 정의한 데이터 형에만 어트리뷰트를 붙일 수 있다.
[AttributeUsage(AttrbuteTargets.Method)]
public class AdditionalInfo { … }
AttributeUsage 역시 Attrbute 이며 사용자가 정의할 어트리뷰트 앞에 사용됨으로서 범위를 지정 할 수 있다. Method 이외에 AttrbuteTargets.Class, AttrbuteTargets.Delegate, AttrbuteTargets.Interface, AttrbuteTargets.Propert, AttrbuteTargets.Construct 등등을 사용 할 수 있다.
만약 여러 개의 데이터 형에 붙일려면 ‘|’를 이용하면 된다.
[AttributeUsage(AttrbuteTargets.Method | AttrbuteTargets.Delegate)]
public class AdditionalInfo { … }
또한 모든 데이터 형에 붙이는 것을 가능하게 할려면 AttrbuteTargets.All 이라고 해 주면 된다.
- 어트리뷰트 클래스 선언
간단히 클래스에 대한 제작자, 업데이트 날짜, 최신 버전을 다운 받을 수 있는 곳 등의 정보를 담을 수 있는 어트리뷰트를 만들어 보도록 하겠다. 다른 클래스를 만드는 것처럼 비슷하게 클래스를 작성 하면 어트리뷰트가 구현된다. 모든 어트리뷰트는 System.Attribute로 부터 상속 받는다. 즉 보통 클래스를 선언하는 똑 같은 방법으로 선언하고 다만 System.Attriute로부터 상속을 받으면 그 클래스가 어트리뷰트가 되는 것이다. 일반 클래스와 구분하기 위해 접미사로 ‘Attribute’를 붙일 것을 권고 한다.
어트리뷰트도 클래스 이므로 생성자가 존재 한다. 다만 어트리뷰트는 하나의 생성자만 가질 수 있다. 즉 생성자 오버로딩이 불가능 하다. 그럼 추가로 받아야 하는 정보들은 어떻게 처리 할까? 어트리뷰트에서는 생성자에서 꼭 집어 넣어야 하는 데이터는 위치지정 파라미터로 받고 부가적인 데이터는 명명 파라미터를 통해 받아 들임으로서 문제를 해결 한다.
[예제]
using System;
[AttributeUsage(AttributeTargets.Class)]
public class AdditionalInfoAttribute: Attribute
{
//생성자에 있는 두개의 인자는 위치지정 파라미터 이다.
//즉 위치지정 파라미터는 클래스에 어트리뷰트를 붙일때 반드시 넘겨 줘야 한다.
//항상 생성자에서 값을 넘겨 주게 되어 있으므로 name, update인 경우 Property에서 set이 없다.
public AdditionalInfoAttribute(string name, string update)
{
this.name = name;
this.update = update;
}
public string Name
{
get { return name; }
}
public string Update
{
get { return update; }
}
public string Download
{
set { download = value; }
get { return download; }
}
string name;
string update;
string download;
}
// 아래의 경우처럼 위치지정 파라미터는 생성자에 값을 그대로 전달하지만 명명 파라미
// 터는 파라미터 이름에 값을 대입하여 생성자에 넘겨야 한다.
[AdditionalInfo(“jclee”,’20094-01-01”, Download = http://www.oraclejavanew.kr)]
class Test { … }
클래스에 어트리뷰트를 붙였다면 반대로 클래스로부터 어떤 어트리뷰트들이 붙어 있는지 아는 하는 방법도 있어야 할 것이다. 바로 전 예제에서Test라는 클래스에 어트리뷰트를 붙였는데 반대로 Test라는 클래스로부터 어트리뷰트 정보를 알아내는 방법을 예제를 통해 보도록 하자.
public class AttrInfo
{
public static void Main ()
{
Type type = typeof(Test);
foreach(Attribute attr in type.GetCustomAttributes(true))
{
AdditionalInfoAttribute info = attr asAdditionalInfoAttribute;
if (info != null)
{
Console.WriteLine("Name={0}, Update={1}, DownLoad={2}", info.Name, info.Update, info.Download);
}
}
}
}
4. 사용자정의 어트리뷰트의 처리 과정
- 어트리뷰트 클래스를 찾는다.
- 어트리뷰트의 범위를 체크 한다.
- 어트리뷰트의 생성자를 체크 한다.
- 객체의 인스턴스를 생성 한다.
- 명명 파라미터들을 체크 한다.
- 명명 파라미터 값으로 필드나 프로퍼티의 값을 설정 한다.
- 어트리뷰트 클래스의 현재 상태를 저장한다.
[개강확정강좌]오라클자바커뮤니티에서 운영하는 개발자 전문교육 ,개인80%환급(www.onjprogramming.co.kr)
[주말]
[11/2]C#,ASP.NET마스터
[11/2]Spring3.X, MyBatis, Hibernate실무과정
[11/2]JAVA&WEB프레임워크실무과정
[평일야간]
[10/29]C#,ASP.NET마스터
[10/31]JAVA&WEB프레임워크실무과정
[11/1]Spring3.X, MyBatis, Hibernate실무과정
[주간]
[11/4]Spring3.X, MyBatis, Hibernate실무과정
[주말]
[11/2]C#,ASP.NET마스터
[11/2]Spring3.X, MyBatis, Hibernate실무과정
[11/2]JAVA&WEB프레임워크실무과정
[평일야간]
[10/29]C#,ASP.NET마스터
[10/31]JAVA&WEB프레임워크실무과정
[11/1]Spring3.X, MyBatis, Hibernate실무과정
[주간]
[11/4]Spring3.X, MyBatis, Hibernate실무과정
[기타 다른 강좌는 아래 해당 카테고리를 클릭해주세요]
댓글 없음:
댓글 쓰기