Wednesday, January 23, 2013

Generic Reflection


Reflection is useful when we need to determine the content of the given assembly. in .net framework reflection is enabled for most of the assemblies because of that when you type the object name and dot ('.') available contents(methods and properties) will automatically list down. but for generic types this is imposible because exact type will recognize at the execution time. For that type of cases you will have to impliment reflection at the code level.reflection is the best way to call the generic method when the type parameter isn't know at the compile time.

Reflection Implementation Main steps

  1. Get the type of object
  2. Use the retrieved type to browse the contents


Ex 01:-


namespace test_console_app
{
    class Program
    {
        static void Main(string[] args)
        {
            Airline airline = new Airline();
            airline.ModelList = new List<string>() {"A1","A2","A3" };
            Requestor requestor = new Requestor();
            requestor.ModelList = new List<string>() { "R1", "R2", "R3" };
            IList<string> airlineModels = GetAirlineModel(airline);
            IList<string> requestorModels = GetRequestorModel(requestor);

        }

        public static IList<string> GetAirlineModel(Airline a)
        {
            return a.ModelList;
        }

        public static IList<string> GetRequestorModel(Requestor r)
        {
            return r.ModelList;
        }

       
      public class Airline
      {
            IList<string> modelList;

            public long Id { get; set; }
            public string Name { get; set; }
            public string Statuse { get; set; }
            public string State { get; set; }
            public IList<string> LocationList { get; set; }
            public IList<string> ModelList
            {
                get { return modelList; }
                set { modelList = value; }
            }

        }

        public class Requestor
        {
            IList<string> modelList;

            public long Id { get; set; }
            public string Name { get; set; }
            public string Statuse { get; set; }
            public string State { get; set; }
            public IList<string> LocationList { get; set; }
            public IList<string> ModelList
            {
                get { return modelList; }
                set { modelList = value; }
            }



        }
    }
}

for the above example you can see that GetAirlineModel and GetRequestorModel methods are behave in the same way so we can write  simple generic method instead of those 2 methods.

 
public static IList<string> GetModel<T>(T obj)
        {
            return obj.GetType().GetProperty("ModelList").GetValue(obj, null) as IList<string>;
        }

Copy properties from one type to another

Ex 02:-

think that you need to create a Airline object by using Requestor Object as following,


public static Airline createAirlineFromRequestor(Requestor r)
        {
            return new Airline()
                {
                    Id = r.Id,
                    LocationList = r.LocationList,
                    ModelList = r.ModelList,
                    Name = r.Name,
                    State = r.State,
                    Statuse = r.Statuse
                };
        }

following is the generic method that you can reuse for different scenarios,

       public static U AssignProperties<T, U>(T obj)
        {
            var newObj = (U)Activator.CreateInstance(typeof(U));
            foreach (var item in newObj.GetType().GetProperties())
            {
                string destinationName = item.Name;
                foreach (var item2 in obj.GetType().GetProperties())
                {
                    string targetName = item2.Name;
                    if (destinationName == targetName)
                    {
                        var value = obj.GetType().GetProperty(targetName).GetValue(obj, null);
                        newObj.GetType().GetProperty(destinationName).SetValue(newObj, value,null);
                    }
                }
            }
            return newObj;
        }
 note:- you can use that method to copy the property values of one type to another if both types have properties with same name

Access to the Inner Properties


Ex 03:-



       public class Airline
        {
           
            public AdvancedPropert Status { get; set; }
            public AdvancedPropert State { get; set; }
           

        }

        public class AdvancedPropert
        {
            public bool IsEditable { get; set; }

            public long AccessId { get; set; }

            public string Value { get; set; }
        }

here you can see State and Status properties are AdvancedPropert type properties as they have inner properties.if you want to access to those inner properties through the generic method you can use following method,

public static void GetAdvancedProperty<T>(T obj)
        {
            var outerValue = obj.GetType().GetProperty("State").GetValue(obj, null);
            var innerValue = outerValue.GetType().GetProperty("IsEditable").GetValue(outerValue, null);
            Console.WriteLine(innerValue);
            Console.ReadLine();
        }


No comments:

Post a Comment