lundi 15 août 2016

Converting hierarchy of Dictionary

I have a base class with a series of classes as public members. I'm trying to convert a Dictionary to this class.

Any idea how to get past this exception? This code seems to work great when the base class contains primitive types and not types that I've created (or lists of types that I've created).

Exception output:

================================================================================
 = Exception Type: System.InvalidCastException
 = Exception Dat System.Collections.ListDictionaryInternal
 = Inner Exception:
 = Exception Message: Object must implement IConvertible.
 = Exception Source: mscorlib
 = Exception StackTrace:    at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType)
   at sandbox.Program.DictToObject[T](IDictionary`2 dict) in D:\Code\Misc\Sandbox\sandbox\Program.cs:line 91
   at sandbox.Program.Main(String[] args) in D:\Code\Misc\Sandbox\sandbox\Program.cs:line 48
================================================================================

Code:

using System;
using System.Collections.Generic;
using System.Reflection;

namespace sandbox
{
    public class BaseClass
    {
        public int SomeInt { get; set; }
        public string SomeString { get; set; }
        public SubClass ScSingleton { get; set; }
        public List<SubClass> ScList { get; set; }
    }

    public class SubClass
    {
        public int AnotherInt { get; set; }
        public string AnotherString { get; set; }
    }

    public partial class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Dictionary<string, object> outer = new Dictionary<string, object>();
                outer.Add("SomeInt", 5);
                outer.Add("SomeString", "foo");

                Dictionary<string, object> scSingle = new Dictionary<string, object>();
                scSingle.Add("AnotherInt", 10);
                scSingle.Add("AnotherString", "bar");
                outer.Add("ScSingleton", scSingle);

                List<Dictionary<string, object>> scList = new List<Dictionary<string, object>>();
                scList.Add(scSingle);
                outer.Add("ScList", scList);

                BaseClass b = DictToObject<BaseClass>(outer);
            }
            catch (Exception e)
            {
                PrintException(e);
            }
            finally
            {
                Console.WriteLine("");
                Console.Write("Press ENTER to exit.");
                Console.ReadLine();
            }

            return;
        }

        public static T DictToObject<T>(IDictionary<string, object> dict) where T : new()
        {
            T t = new T();
            PropertyInfo[] properties = t.GetType().GetProperties();

            foreach (KeyValuePair<string, object> curr in dict)
            {
                if (String.IsNullOrEmpty(curr.Key)) continue;
                if (curr.Value == null) continue;

                Type valType = null;
                Type newType = null;
                PropertyInfo currProperty = null;
                foreach (PropertyInfo p in properties)
                {
                    if (String.IsNullOrEmpty(p.Name)) continue;

                    if (String.Compare(p.Name.ToLower(), curr.Key.ToLower()) == 0)
                    {
                        valType = t.GetType().GetProperty(p.Name).PropertyType;
                        newType = Nullable.GetUnderlyingType(valType) ?? valType;
                        currProperty = p;
                        break;
                    }
                }

                object newVal = Convert.ChangeType(curr.Value, newType);
                t.GetType().GetProperty(currProperty.Name).SetValue(t, newVal);
            }

            return t;
        }

        static void PrintException(Exception e)
        {
            Console.WriteLine("================================================================================");
            Console.WriteLine(" = Exception Type: " + e.GetType().ToString());
            Console.WriteLine(" = Exception Dat " + e.Data);
            Console.WriteLine(" = Inner Exception: " + e.InnerException);
            Console.WriteLine(" = Exception Message: " + e.Message);
            Console.WriteLine(" = Exception Source: " + e.Source);
            Console.WriteLine(" = Exception StackTrace: " + e.StackTrace);
            Console.WriteLine("================================================================================");
        }
    }
}





Aucun commentaire:

Enregistrer un commentaire