Підрозділ 14.Q
Питання для самоконтролю
Питання для самоконтролю — Розділ 14. Рефлексія 14.1. Введення у рефлексію. Клас System.Type 1. Що таке рефлексія і що робить її можливою у .NET? Чому збірки .dll і .exe містять не лише IL код, але й метадані?
Питання для самоконтролю — Розділ 14. Рефлексія
14.1. Введення у рефлексію. Клас System.Type
Що таке рефлексія і що робить її можливою у .NET? Чому збірки
.dllі.exeмістять не лише IL-код, але й метадані?Назвіть п'ять реальних інструментів або фреймворків (DI-контейнери, ORM, тестові фреймворки), які використовують рефлексію «під капотом». Поясніть, для чого саме вона їм потрібна.
В чому різниця між трьома способами отримати об'єкт
Type:typeof(PatientRecord)patient.GetType()Type.GetType("PatientRecord")Коли кожен із них є єдиним або кращим вибором?
Що виведе наступний код? Поясніть результат:
object obj = new InpatientRecord("R001", 7); Console.WriteLine(obj.GetType().Name); Console.WriteLine(typeof(MedicalRecord).Name); Console.WriteLine(obj.GetType() == typeof(MedicalRecord));(де
InpatientRecordуспадковуєMedicalRecord)Яке головне застереження щодо продуктивності рефлексії? В яких частинах програми вона доречна, а в яких — ні?
Що повертає
GetInterfaces()і чому кожний елемент масиву є об'єктомType, а не рядком?Що повертає
Type.IsAssignableFrom(other)і чим це відрізняється відother.IsSubclassOf(type)? Напишіть перевірку, яка визначає, чи реалізує типtінтерфейсIDisposable.Спроєктуйте функцію
PrintTypeInfo(Type t), яка виводить: ім'я типу, чи є він класом/структурою/інтерфейсом, базовий клас і список реалізованих інтерфейсів.
14.2. Застосування рефлексії та дослідження типів
Що таке
MemberInfoі чомуGetMembers()повертає саме цей тип, а не конкретнішіMethodInfoчиFieldInfo?Поясніть різницю між
DeclaringTypeтаReflectedTypeдля члена типу. Наведіть конкретний приклад з ієрархією класів, де вони відрізняються.Що таке
BindingFlags? Чому при явній передачі прапорців потрібно вказувати всі потрібні категорії (наприклад, іPublic, іInstance)?Що виведе наступний код і чому
nameне з'являється у списку?Type t = typeof(Person); foreach (var m in t.GetMembers()) Console.WriteLine($"{m.MemberType} {m.Name}"); public class Person { string name; public int Age { get; set; } }Що таке «backing field» автовластивості (
<Name>k__BackingField)? Як його виявити через рефлексію і чому потрібно вміти відрізняти backing fields від звичайних полів?Напишіть код, який отримує тільки власні (не успадковані) публічні та приватні методи-екземпляри класу
PatientRecord, використовуючи правильну комбінаціюBindingFlags.Чому
GetMember("AddNote")може повернути масив з кількох елементів? Як отримати конкретне перевантаження методу, якщо потрібна версія з параметрами(string, DateTime)?Опишіть практичний сценарій, де необхідно динамічно аналізувати структуру невідомого класу (наприклад, у системі звітності або серіалізатора), і поясніть, який набір
BindingFlagsпідходить для отримання повної картини типу.
14.3. Дослідження методів та конструкторів за допомогою рефлексії
Що таке
MethodInfo? Які властивості дозволяють визначити, є методpublic,private,static,virtualабоabstract?Що таке
IsSpecialNameдля методів і для чого воно потрібне? Чому при виведенні списку методів типу часто фільтрують!m.IsSpecialName?Що виведе наступний код? Який тип результату і чому?
var patient = new PatientRecord("Іван", new DateTime(1985, 1, 1)); MethodInfo m = typeof(PatientRecord).GetMethod("GetSummary")!; object? result = m.Invoke(patient, null); Console.WriteLine(result?.GetType().Name);Що таке
TargetInvocationExceptionі чому CLR перегортає реальне виключення в цю обгортку? Як правильно «розпакувати» справжнє виключення?В чому різниця між
ConstructorInfo.InvokeіActivator.CreateInstance? Назвіть сценарій, де краще використовувати кожен із підходів.Що таке
.cctor(статичний конструктор) з точки зору рефлексії? Чому його можна побачити черезGetConstructors, але не можна викликати черезInvoke?Напишіть код, який динамічно викликає метод
SetBmi(decimal)для масиву пацієнтів, кешуючиMethodInfoу статичне поле, а не шукаючи його щоразу всередині циклу.Що таке
MethodInfo.CreateDelegateі яку перевагу він дає порівняно зInvoke? Для якого сценарію використання делегат є кращим вибором: одноразовий виклик чи виклик у циклі на тисячах об'єктів?
14.4. Дослідження полів та властивостей за допомогою рефлексії
В чому принципова відмінність між
FieldInfoіPropertyInfo? Чому властивість — це абстракція, а не просто «поле з доступом»?Що виведе наступний код і чому?
public class Patient { public const int MaxAge = 150; public readonly string Ward = "Cardiology"; } var fi = typeof(Patient).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); foreach (var f in fi) Console.WriteLine($"{f.Name}: IsLiteral={f.IsLiteral}, IsInitOnly={f.IsInitOnly}");Як прочитати значення приватного поля
_bmiоб'єкта через рефлексію? Напишіть код із правильнимBindingFlags.Що таке
init-аксесор у C# 9 і чомуPropertyInfo.CanWriteможе вводити в оману? Як обійти обмеженняinitчерезFieldInfo.SetValue?Як прочитати значення статичного поля через
FieldInfo.GetValue(null)? Що означаєnullяк аргумент у цьому контексті?Назвіть три реальні сценарії застосування
PropertyInfo.GetValueіPropertyInfo.SetValueу відомих вам фреймворках або бібліотеках.Напишіть метод
static void PrintProperties(object obj), який через рефлексію виводить імена і значення всіх публічних властивостей об'єкта. Обробіть випадок, колиCanRead = false.Спроєктуйте спрощений клонувальник
ShallowClone<T>(T source), який черезFieldInfoкопіює всі поля (крімconst) у новий об'єкт, створений без конструктора черезFormatterServices.GetUninitializedObject. Поясніть, чомуconst-поля (IsLiteral) потрібно пропускати.
14.5. Динамічне завантаження збірок та пізнє зв'язування
В чому різниця між статичним і динамічним завантаженням збірок? Який сценарій вимагає динамічного завантаження?
Порівняйте
Assembly.LoadFrom(path)іAssembly.LoadFile(path). В яких ситуаціях кожен із них використовується і в чому їхня різниця у вирішенні залежностей?Що таке
AssemblyLoadContext(ALC) і яку проблему він вирішує порівняно зAppDomainу .NET Framework? Що означаєisCollectible: true?Чому
GetTypes()може кинутиReflectionTypeLoadExceptionі як правильно обробити цю ситуацію? Яка альтернатива є надійнішою?Опишіть 6 кроків плагінної архітектури через рефлексію: від визначення інтерфейсу до виклику методів плагіна через цей інтерфейс.
Що означає
pluginInterface.IsAssignableFrom(t)у контексті сканування типів? Чим це відрізняється відt.IsSubclassOf(pluginInterface)?Що виведе наступний код? Чому перевірка
!t.IsAbstract && !t.IsInterfaceє важливою?Type iface = typeof(IAnalysisPlugin); var candidates = assembly.GetExportedTypes() .Where(t => iface.IsAssignableFrom(t)); Console.WriteLine(candidates.Count());(де збірка містить:
IAnalysisPlugin(інтерфейс),BmiPlugin : IAnalysisPlugin,AbstractPlugin : IAnalysisPlugin(abstract))Поясніть, що потрібно для коректного
Unload()уAssemblyLoadContext. Які три умови мають бути виконані? Що відбувається, якщо хоч одна не виконана?
14.6. Атрибути у .NET
Що таке атрибут у .NET? Від якого класу успадковують всі атрибути і де зберігаються їхні дані після компіляції?
Поясніть різницю між позиційними аргументами атрибута та іменованими аргументами:
[MedRange(10.0, 60.0, Message = "ІМТ поза нормою")]Які з цих аргументів потрапляють у конструктор, а які — у властивості?
Що таке
[AttributeUsage]? Поясніть, що задають параметриAttributeTargets,AllowMultipleіInherited.Що виведе наступний код і чому?
[AttributeUsage(AttributeTargets.Class, Inherited = true)] public sealed class MarkerAttribute : Attribute { } [Marker] public class Base { } public class Derived : Base { } Console.WriteLine(typeof(Derived).IsDefined(typeof(MarkerAttribute), true)); Console.WriteLine(typeof(Derived).IsDefined(typeof(MarkerAttribute), false));Чому рекомендується оголошувати класи атрибутів як
sealed? Чому за конвенцією назви атрибутів мають суфіксAttribute, і як це впливає на синтаксис застосування?Назвіть чотири методи для читання атрибутів через рефлексію і поясніть, чим вони відрізняються. Який із них найшвидший для простої перевірки «чи є атрибут»?
Напишіть власний атрибут
[MedRequired]і клас-валідатор, який через рефлексію перевіряє всі публічні властивості об'єкта і повертає список назв властивостей, що мають цей атрибут, але значення яких єnullабо порожнім рядком.Порівняйте
GetCustomAttribute<T>()іGetCustomAttributesData(). Коли варто використовувати другий метод? Наведіть приклад ситуації, де важливо отримати дані атрибута без виклику його конструктора.