My Blog

Creare istanze di oggetti con parametri opzionali mediante Reflection

by lupok on lunedì 3 dicembre 2012 20:36
Creare istanze di oggetti con parametri opzionali mediante Reflection

In questo esempio viene mostrato come è possibile automatizzare la creazione di istanze che prevedono parametri opzionali nel costruttore mediante reflection, in particolare l'esempio si riferisce al caso in cui un sottoinsieme dei parametri necessari per creare l'istanza derivino dagli argomenti passati a linea di comando:

Creiamo un progetto console che utilizzeremo per testare il codice che andremo a scrivere:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CreateObjectInstanceWithOptionalParameters
{
   class Program
   {
      static void Main(string[] args)
      {
      }
   }
}


Quindi aggiungiamo un'enumerazione che utilizzeremo a scopo di esempio:

      public enum MyEnum
      {
         One,

         Two,
      }


Ed una classe che prevede parametri opzionali nel costruttore:

      public class MyClass
      {
         public MyClass(MyEnum myEnum = MyEnum.One, int myInt = 12, double myDouble = 34.9)
         {
            MyEnum = myEnum;
            MyInt = myInt;
            MyDouble = myDouble;
         }

         public MyEnum MyEnum { get; set; }
         public int MyInt { get; set; }
         public Double MyDouble { get; set; }

      }





Attraverso la funzione riportata di seguito è possibile creare un'istanza dove una parte, tutti o nessuno dei parametri necessari per creare l'istanza sono specificati come argomenti (parametro arguments)


      static T CreateDefaultInstance(String[] arguments)
      {
         var ctrs = typeof(T).GetConstructors();
         System.Reflection.ConstructorInfo ci = ctrs.FirstOrDefault();

         var l = new List();
         System.Reflection.ParameterInfo[] parameters = ci.GetParameters();

         for (int i = 0; i < parameters.Length; i++)
         {
            if (arguments.Length > parameters[i].Position)
            {
               if (parameters[i].ParameterType.IsEnum)
                  l.Add(Enum.Parse(parameters[i].ParameterType, arguments[parameters[i].Position]));
               else
                  l.Add(Convert.ChangeType(arguments[parameters[i].Position], parameters[i].ParameterType));
            }
            else
               l.Add(parameters[i].RawDefaultValue);
         }
         return (T)ci.Invoke(l.ToArray());
      }


Quindi per create una nuova istanza dell'oggetto ipotizzando che un sottinsieme dei parametri previsti dal costruttore siano passati da linea di comando:


      static void Main(string[] args)
      {
         MyClass myClass = CreateDefaultInstance(args);

         foreach (System.Reflection.PropertyInfo pi in myClass.GetType().GetProperties())
         {
            Console.WriteLine(String.Format("{0} = {1}", pi.Name, pi.GetValue(myClass, null)));
         }
      }



Quindi proviamo ad eseguire l'applicazione con parametri a linea di comando:


C:\Temp\CreateObjectInstanceWithOptionalParameters.exe Two 101 234,765







Naturalmente questo frammento di codice si può estendere per gestire casi più complessi.

Blogs Parent Separator My Blog
Author
lupok

My Blog

Tags