Механизм рефлексии метаданных — это способность получать информацию о типах данных на этапе выполнения программы. Класс Assembly позволяет получить общую информацию о текущей сборке, например:
Console.WriteLine(Assembly.GetExecutingAssembly().ManifestModule.Name);
Сборки обеспечивают инфраструктуру, которая помогает CLR разбирать содержимое приложений, узнавать зависимости между ними, определять их версии. Концепция сборки являются главным средством, с помощью которого решаются проблемы размещения приложений и управления ими. Сборки позволяют проверять права пользователей на запуск приложений. Они также способны проверять права самого кода на выполнение определенных действий (доступ к папкам и файлам, запуск сервисов).
Основным классом пространства имен System является Type. Он позволяет получить исчерпывающую информацию о любом типе данных. Следующий фрагмент кода позволяет получить информацию обо всех типа текущей сборки.
string assemblyName = Process.GetCurrentProcess().ProcessName + ".exe";
Console.WriteLine("\n\tAssemblyName: {0}", assemblyName);
Assembly ass = Assembly.GetExecutingAssembly();
Type[] types = ass.GetTypes();
foreach (Type type in types)
{
Console.WriteLine("\nType: {0}", type);
foreach (MemberInfo member in type.GetMembers())
Console.WriteLine("\tMember: {0}", member);
}
В нашем случае мы получим данные об одном типе: классе Test. Так как наш класс Test, как и все другие типы .NET происходит от класса Object, то он получил в наследство все его методы.
AssemblyName: ConsoleApplication1.exe
Type: Test
Member: Void Main()
Member: System.Type GetType()
Member: System.String ToString()
Member: Boolean Equals(System.Object)
Member: Int32 GetHashCode()
Member: Void .ctor()
Другие классы:
¨ MemberInfo, LocalVariableInfo, ParameterInfo,
¨ FieldInfo, ConstructorInfo, MethodInfo, PropertyInfo, EventInfo, позволяют копаться в мета-данных сборки. Например:
Type type = typeof(Exception);
MemberInfo[] members = type.GetMembers();
foreach (MemberInfo info in members)
{
MemberTypes types = info.MemberType;
Console.WriteLine("{0,20} is a {1}", info.Name, types);
}
Заметьте, что этот фрагмент допускает более краткую запись:
Console.WriteLine ("\nException Members\n");
foreach (MemberInfo info in typeof(Exception).GetMembers())
Console.WriteLine("{0,20} is a {1}", info.Name, info.MemberType);
Наш фрагмент выведет такую информацию.
Exception Members
get_Message is a Method
get_Data is a Method
GetBaseException is a Method
get_InnerException is a Method
get_TargetSite is a Method
get_StackTrace is a Method
get_HelpLink is a Method
set_HelpLink is a Method
get_Source is a Method
set_Source is a Method
ToString is a Method
GetObjectData is a Method
GetType is a Method
GetType is a Method
Equals is a Method
GetHashCode is a Method
.ctor is a Constructor
.ctor is a Constructor
.ctor is a Constructor
Message is a Property
Data is a Property
InnerException is a Property
TargetSite is a Property
StackTrace is a Property
HelpLink is a Property
Source is a Property
Все типы в .NET происходят от класса Object. Убедимся в этом.
int i = int.MaxValue; // 2147483647 is of type System.Int32
Console.WriteLine("\n\n{0,20} is of type {1}", i, i.GetType());
Type type = typeof(int);
Console.WriteLine("\n{0,20} is a child of object: {1}", type.Name,
type.IsSubclassOf(typeof(object)));
Информацию о типе можно получить и по его имени.
type = Type.GetType("System.ValueType"); // ValueType is located in: CommonLanguageRuntimeLibrary
Console.WriteLine("\n{0,20} is located in: {1}", type.Name, type.Module);
С помощью рефлексии вы можете легко реализовать один из стандартных шаблонов проектирования, называемый Abstract Factory. Смысл его создай объект, тип которого неизвестен во время компиляции, но он будет известен во время выполнения. С этой задачей легко справляется класс Activator и его метод CreateInstance. Покажем, как это делается. По умолчанию мы создадим "объект класса" int, а затем тип создаваемого объекта будет определять пользователь.
for (string name = "System.Int32"; name != ""; )
{
try
{
Type type = Type.GetType(name);
if (type != null)
{
object o = Activator.CreateInstance(type);
Console.WriteLine("\nCreated: {0}, Default value: {1}", o.GetType(), o.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Write("\nEnter a type name: ");
name = Console.ReadLine();
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.