메타 데이터는 '데이터에 대한 데이터'이다. 쉽게 말하면 어떤 자료형이 어떤 구조로 이루어져있는가에 대한 데이터라는 뜻이다. 자료형의 이름은 무엇이며, 어떤 멤버를 가지고있고, 멤버의 이름은 무엇이며... 등등의 정보를 메타데이터라고 한다.
메타데이터는 컴파일 타임에 어셈블리파일(exe, dll)에 저장된다. 어셈블리 파일은 'Module'을 포함하며, Module 클래스는 어셈블리 내부의 코드와 리소스를 추상화한 클래스다. 어셈블리에는 여러 형식(자료형)과 해당 형식의 멤버에 대한 메타데이터가 포함된다.
Reflection은 메타데이터에 접근하고 읽고 쓰기 위한 여러 메서드를 제공한다 . namespace System.Reflection에는 interface IReflect가 제공된다. Type과 같은 메타데이터 클래스들은 해당 인터페이스를 상속받아 여러 동작을 수행할수 있다.
Attribute는 개발자가 메타데이터에 추가할 수 있는 정보이다. 사용하기 쉽도록 미리 언어나 엔진차원에서 구현되어있는 Attribute도 있고, 사용자 정의 Attribute를 만들 수 도 있다. 또한 해당 Attribute가 타겟으로 하는 특정 요소가 컴파일될 때 어떻게 동작해야하는지도 정의할 수 있다.
다음은 함수, 클래스에 작성 개발자와 버전을 메타데이터에 넣을 수 있도록 작성한 사용자 정의 Attribute이다.
namespace CustomAttribute
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public MyAttribute(string name, int version)
{
Name = name;
Version = version;
}
public string Name
{
get;
}
public int Version
{
get;
}
}
[My("Hwang Seung Min", 3)]
public class MyClass
{
[My("Hwang Soo Min", 1)]
public void TestMessage()
{
Console.WriteLine("MyClass : Test Message");
}
}
internal class Program
{
static void Main(string[] args)
{
Type ClassType = typeof(MyClass);
object[] Attributes = ClassType.GetCustomAttributes(false);
foreach (var Attribute in Attributes)
{
if (Attribute is MyAttribute developerAttr)
{
Console.WriteLine($"Class developed by {developerAttr.Name}, version {developerAttr.Version}");
}
}
}
}
}