Рефлексія, особливо про приватних членів, неправильна
- Відбиття порушує безпеку типу. Ви можете спробувати викликати метод, який не існує (більше), або з неправильними параметрами, або з занадто великими параметрами, або недостатньо ... або навіть у неправильному порядку (цей мій улюблений :)). До речі, тип повернення також може змінитися.
- Рефлексія повільна.
Відображення приватних членів порушує принцип інкапсуляції і, таким чином, виставляє ваш код наступному:
- Збільште складність свого коду, оскільки він повинен керувати внутрішньою поведінкою класів. Те, що приховано, має залишатися прихованим.
- Робить код зручним, оскільки він буде компілюватися, але не запуститься, якщо метод змінив ім'я.
- Робить приватний код зручним, тому що якщо він приватний, його не потрібно називати таким чином. Можливо, приватний метод очікує деякого внутрішнього стану, перш ніж викликати.
Що робити, якщо я все одно повинен це зробити?
Бувають такі випадки, коли ти залежиш від третьої сторони або тобі потрібні певні апі, які не піддаються впливу, то ти повинен зробити певне роздуми. Деякі також використовують його для тестування деяких класів, якими вони володіють, але вони не хочуть змінювати інтерфейс, щоб надати доступ до внутрішніх членів лише для тестів.
Якщо ви це зробите, зробіть це правильно
Щоб пом'якшити проблему, яку можна легко зламати, найкраще - виявити будь-який потенційний зрив, випробувавши в одиничних тестах, які працюватимуть у безперервній збірці інтеграції тощо. Звичайно, це означає, що ви завжди використовуєте ту саму збірку (яка містить приватних членів). Якщо ви використовуєте динамічне навантаження та роздуми, вам подобається грати з вогнем, але ви завжди можете зловити виняток, який може викликати виклик.
- Пом'якшити повільність відображення:
В останніх версіях .Net Framework, CreateDelegate перемістив на коефіцієнт 50 виклик MethodInfo:
// The following should be done once since this does some reflection
var method = this.GetType().GetMethod("Draw_" + itemType,
BindingFlags.NonPublic | BindingFlags.Instance);
// Here we create a Func that targets the instance of type which has the
// Draw_ItemType method
var draw = (Func<TInput, Output[]>)_method.CreateDelegate(
typeof(Func<TInput, TOutput[]>), this);
draw
виклики будуть приблизно в 50 разів швидше, ніж MethodInfo.Invoke
використання draw
як стандартного Func
типу:
var res = draw(methodParams);
Перевірте цей мій пост, щоб побачити орієнтир для різних викликів методів