Хочу поделится некоторыми полезными для себя вещами, которые я использую в работе. Это первая часть статей, в планах написать несколько, развивая последовательно тему. Хочу заметить сразу, что не претендую на совершенный код, наоборот, с вашими замечаниями надеюсь сделать свои инструменты еще более производительными и полезными.
Первая статья скорее вводная, в ней я хочу определить несколько полезных extension методов для механизма отражений. Эти методы в дальнейшем пригодятся при построении моих инструментов. Данная статья может быть бесполезной для большинства программистов, поэтому не надеюсь на ее популярность. Но все же, думаю, что замечания и к ней возникнут тоже.
Как известно в .net есть механизм отражений (reflection), который позволяет получать информацию о классах во время исполнения. Не буду расписывать что и как и зачем. Сразу к делу: в отражениях есть несколько однотипных классов FieldInfo, ProppertyInfo и некоторый объединяющий (базовый) класс MemberInfo. Когда мы программируем атрибуты для полей и свойств сразу, то для обработки мы можем последовательно выбирать поля и потом свойства либо получить сразу все через MemberInfo. Я остановился на последнем варианте, но по понятным причинам этот класс слегка обрезан по сравнению с другими классами. Например у него нет методов SetValue, GetValue, да и тип для полей и свойств хотелось бы получать сразу. В связи с этим предлагаю такое решение:
Данные методы позволяют через MemberInfo задавать значения полям и свойствам, получать эти значения, а также узнавать типы. В случае попытки установить значение не полю или свойству генерируется исключение.
Первая статья скорее вводная, в ней я хочу определить несколько полезных extension методов для механизма отражений. Эти методы в дальнейшем пригодятся при построении моих инструментов. Данная статья может быть бесполезной для большинства программистов, поэтому не надеюсь на ее популярность. Но все же, думаю, что замечания и к ней возникнут тоже.
Как известно в .net есть механизм отражений (reflection), который позволяет получать информацию о классах во время исполнения. Не буду расписывать что и как и зачем. Сразу к делу: в отражениях есть несколько однотипных классов FieldInfo, ProppertyInfo и некоторый объединяющий (базовый) класс MemberInfo. Когда мы программируем атрибуты для полей и свойств сразу, то для обработки мы можем последовательно выбирать поля и потом свойства либо получить сразу все через MemberInfo. Я остановился на последнем варианте, но по понятным причинам этот класс слегка обрезан по сравнению с другими классами. Например у него нет методов SetValue, GetValue, да и тип для полей и свойств хотелось бы получать сразу. В связи с этим предлагаю такое решение:
namespace Xaoc.BasicClasses { public static class ReflectionUtil { public static void SetValue(this MemberInfo p_member, object obj, object value) { if (p_member == null || obj == null) throw new Exception("Недопустимые параметры"); switch (p_member.MemberType) { case MemberTypes.Field: (p_member as FieldInfo).SetValue(obj, value); break; case MemberTypes.Property: if ((p_member as PropertyInfo).CanWrite) (p_member as PropertyInfo).SetValue(obj, value, null); else throw new Exception("Свойство не может быть изменено"); break; default: throw new Exception("Не совместимый тип MemberTypes"); } } public static object GetValue(this MemberInfo p_member, object obj) { if (p_member == null || obj == null) throw new Exception("Недопустимые параметры"); object result = null; switch (p_member.MemberType) { case MemberTypes.Field: result = (p_member as FieldInfo).GetValue(obj); break; case MemberTypes.Property: if ((p_member as PropertyInfo).CanRead) result = (p_member as PropertyInfo).GetValue(obj, null); else throw new Exception("Невозможно получить значение свойства"); break; default: throw new Exception("Не совместимый тип MemberTypes"); } return result; } public static Type GetMemberType(this MemberInfo p_member) { if (p_member == null) throw new Exception("Недопустимые параметры"); Type result = null; switch (p_member.MemberType) { case MemberTypes.Field: result = (p_member as FieldInfo).FieldType; break; case MemberTypes.Property: result = (p_member as PropertyInfo).PropertyType; break; default: throw new Exception("Не совместимый тип MemberTypes"); } return result; } } }
Данные методы позволяют через MemberInfo задавать значения полям и свойствам, получать эти значения, а также узнавать типы. В случае попытки установить значение не полю или свойству генерируется исключение.