MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Aplicarea reflecției și investigarea tipurilor

Obținerea tuturor componentelor unui tip

Metoda GetMembers() returnează toate componentele disponibile ale unui tip sub formă de obiecte MemberInfo. Acest obiect permite extragerea anumitor informații despre componenta tipului. În particular, unele dintre proprietățile sale sunt:

  • DeclaringType: returnează numele complet al tipului
  • MemberType: returnează o valoare din enumerația MemberTypes: - MemberTypes.Constructor - MemberTypes.Method - MemberTypes.Field - MemberTypes.Event - MemberTypes.Property - MemberTypes.NestedType
  • Name: returnează numele componentei

Aplicarea metodei GetMembers pentru a afișa toate elementele disponibile ale unui tip:

using System.Reflection;     // adăugăm funcționalitatea reflecției

Type myType = typeof(Person);

foreach (MemberInfo member in myType.GetMembers())
{
   Console.WriteLine($"{member.DeclaringType} {member.MemberType} {member.Name}");
}

public class Person
{
   string name;
   public int Age { get; set; }
   public Person(string name, int age)
   {
       this.name = name;
       this.Age = age;
   }
   public void Print() => Console.WriteLine($"Name: {name} Age: {Age}");
}

În acest caz, vom obține toți membrii publici ai clasei Person:

Person Method get_Age
Person Method set_Age
Person Method Print
System.Object Method GetType
System.Object Method ToString
System.Object Method Equals
System.Object Method GetHashCode
Person Constructor .ctor
Person Property Age

Observați că în acest caz obținem doar membrii publici ai clasei și nu se afișează informații despre variabila privată name. De asemenea, pentru proprietate sunt afișate metodele de acces - getter-ul (get_Age) și setter-ul (set_Age). În mod implicit, obținem toate funcționalitățile, inclusiv cele moștenite de la clasele de bază (în acest caz, funcționalitatea clasei de bază Object).

BindingFlags

În exemplul de mai sus, am folosit forma simplă a metodei GetMembers(), care extrage toate metodele publice disponibile. Dar putem folosi și o altă formă a metodei: MembersInfo[] GetMembers(BindingFlags). Enumerația BindingFlags poate accepta diverse valori:

  • DeclaredOnly: obține doar metodele specificate direct în clasa curentă, metodele moștenite nu sunt extrase
  • Instance: obține doar metodele instanței
  • NonPublic: extrage metodele non-publice
  • Public: obține doar metodele publice
  • Static: obține doar metodele statice

Combinând aceste valori folosind operația bitwise OR, putem combina rezultatele. De exemplu, obținem doar componentele clasei directe fără cele moștenite, atât publice, cât și non-publice:

using System.Reflection;     // adăugăm funcționalitatea reflecției

Type myType = typeof(Person);

foreach (MemberInfo member in myType.GetMembers(BindingFlags.DeclaredOnly
           | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
   Console.WriteLine($"{member.DeclaringType} {member.MemberType} {member.Name}");
}

public class Person
{
   string name;
   public int Age { get; set; }
   public Person(string name, int age)
   {
       this.name = name;
       this.Age = age;
   }
   public void Print() => Console.WriteLine($"Name: {name} Age: {Age}");
}

În acest caz, vom obține un rezultat diferit:

Person Method get_Age
Person Method set_Age
Person Method Print
Person Constructor .ctor
Person Property Age
Person Field name
Person Field <Age>k__BackingField

Obținerea unei singure componente după nume

Pentru a obține o singură componentă, putem folosi metoda GetMember(), căreia îi transmitem numele componentei. Opțional, putem transmite și valorile BindingFlags.

Type myType = typeof(Person);

// obținem metoda Print
MemberInfo[] print = myType.GetMember("Print", BindingFlags.Instance | BindingFlags.Public);
foreach (MemberInfo member in print)
{
   Console.WriteLine($"{member.MemberType} {member.Name}");
}

Este important de menționat că la obținerea unui membru al tipului, se returnează din nou un array de MemberInfo[], deoarece într-o clasă pot exista mai multe elemente cu același nume, de exemplu, mai multe versiuni suprasolicitate ale metodei Print.

← Lecția anterioară Lecția următoare →