Come lavorare con la riflessione in C #

La riflessione in C # viene usata per recuperare i metadati sui tipi in fase di esecuzione. In altre parole, è possibile utilizzare la reflection per esaminare dinamicamente i metadati dei tipi nel programma: è possibile recuperare le informazioni sugli assembly caricati e sui tipi definiti in essi. La riflessione in C # è simile a RTTI (Runtime Type Information) di C ++.

Per lavorare con la reflection in .Net, dovresti includere lo spazio dei nomi System.Reflection nel tuo programma. Utilizzando la reflection, si ottengono oggetti del tipo "Type" che possono essere utilizzati per rappresentare assembly, tipi o moduli. È possibile utilizzare la reflection per creare un'istanza di un tipo in modo dinamico e persino richiamare metodi del tipo.

I tipi definiti nello spazio dei nomi System.Reflection includono quanto segue.

  • Assemblaggio
  • Modulo
  • Enum
  • MethodInfo
  • ConstructorInfo
  • MemberInfo
  • ParameterInfo
  • genere
  • FieldInfo
  • EventInfo
  • PropertyInfo

Esaminiamo ora un codice per mettere in azione la riflessione. Considera la seguente classe chiamata Customer.

public class Customer

    {

        public int Id

        {

            get; set;

        }

        public string FirstName

        {

            get; set;

        }

        public string LastName

        {

            get; set;

        }

        public string Address

        {

            get; set;

        }

    }

Il frammento di codice seguente mostra come ottenere il nome della classe e il nome dello spazio dei nomi della classe Customer utilizzando la reflection:

Type type = typeof(Customer);

Console.WriteLine("Class: " + type.Name);

Console.WriteLine("Namespace: " + type.Namespace);

Il seguente frammento di codice illustra come recuperare l'elenco delle proprietà della classe Customer e visualizzarne i nomi nella finestra della console:

static void Main(string[] args)

        {

            Type type = typeof(Customer);

            PropertyInfo[] propertyInfo = type.GetProperties();

            Console.WriteLine("The list of properties of the Customer class are:--");

            foreach (PropertyInfo pInfo in propertyInfo)

            {

                Console.WriteLine(pInfo.Name);

            }

        }

Il metodo GetProperties () della classe Type restituisce un array di tipo PropertyInfo - questo è in realtà un elenco delle proprietà pubbliche del tuo tipo. È quindi possibile iterare questo array e recuperare i nomi di ciascuna delle proprietà pubbliche definite nel tipo. Poiché la classe Customer definisce tre proprietà, i nomi di tutte queste tre proprietà verrebbero visualizzati nella console quando viene eseguito questo programma.

Ecco come possiamo visualizzare i metadati dei costruttori e dei metodi pubblici di un tipo usando la reflection. Rivediamo la classe Customer che abbiamo creato in precedenza e incorporiamo due metodi: un costruttore predefinito e un metodo chiamato Validate che viene utilizzato per convalidare l'oggetto cliente passato ad esso come parametro. Questo è l'aspetto della versione modificata della classe Customer.

public class Customer

    {

        public Customer()

        {

            //Default constructor

        }

        public int Id

        {

            get; set;

        }

        public string FirstName

        {

            get; set;

        }

        public string LastName

        {

            get; set;

        }

        public string Address

        {

            get; set;

        }

        public bool Validate(Customer customerObj)

        {

            //Code to validate the customer object

            return true;

        }

    }

Il seguente frammento di codice può essere utilizzato per visualizzare i nomi di tutti i costruttori che appartengono alla classe Customer. Abbiamo un solo costruttore nella classe Customer, quindi ne verrà elencato solo uno.

Type type = typeof(Customer);           

ConstructorInfo[] constructorInfo = type.GetConstructors();

Console.WriteLine("The Customer class contains the following Constructors:--");

foreach (ConstructorInfo c in constructorInfo)

  {

     Console.WriteLine(c);

  }

Notare che il metodo GetConstructors () della classe Type restituisce un array di tipo ConstructorInfo che contiene l'elenco di tutti i costruttori pubblici definiti nel tipo che viene riflesso.

OK; mostriamo ora i nomi di tutti i metodi pubblici della classe Customer - di nuovo, ne abbiamo solo uno in modo che il nome di un solo metodo venga visualizzato nella console quando viene eseguito il programma indicato successivamente. Ecco l'elenco dei codici come riferimento.

static void Main(string[] args)

 {

    Type type = typeof(Customer);

    MethodInfo[] methodInfo = type.GetMethods();

     Console.WriteLine("The methods of the Customer class are:--");

            foreach (MethodInfo temp in methodInfo)

            {

              Console.WriteLine(temp.Name);               

            }

            Console.Read();

        }

Tieni presente che potresti visualizzare anche i nomi di alcuni metodi aggiuntivi (ToString, Equals, GetHashCode, GetType). Questi metodi vengono ereditati dalla classe Object: qualsiasi classe in .Net deriva la classe Object per impostazione predefinita.

Puoi anche scorrere gli attributi di un metodo. Se sono stati definiti attributi personalizzati per i metodi, è possibile utilizzare il metodo GetCustomAttributes sull'istanza della classe MethodInfo per recuperare gli attributi del metodo. Ecco come puoi ottenerlo.

foreach (MethodInfo temp in methodInfo)

 {

    foreach (Attribute attribute in temp.GetCustomAttributes(true))

     {

         //Write your usual code here

     }

  }

Quindi, se decori i tuoi oggetti business utilizzando attributi nella tua applicazione, puoi sfruttare la riflessione per riflettere sul tipo, recuperare gli attributi dei metodi del tuo tipo e quindi eseguire alcune azioni di conseguenza.