首页 > 技术文章 > 将Object转换成Dictionary方法

sobaby 2015-03-30 16:20 原文

如果Object是Dictionary类型,直接返回

如果Object是NameValueCollection类型,则添加到Dictionary里

如果Object是Hashtable类型,添加到Dictionary里

...其他键值类型请自己完善

如果Object非上述类型,则用IL语言将其转换成Dictionary类型,

具体代码如下:

  public static Dictionary<string, object> ConvertFromObject(object obj)
        {
            if (obj is Dictionary<string, object>) 
                return (Dictionary<string, object>)obj;

            var nvc = obj as NameValueCollection;
            if (nvc != null)
            {
                Dictionary<string, object> dict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                foreach (string key in nvc.Keys)
                    dict.Add( key, nvc[key]);
                return dict;
            }

            var hs = obj as Hashtable;
            if (hs != null)
            {
                Dictionary<string, object> dict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                foreach (string key in hs.Keys.OfType<string>())
                    dict.Add(key, hs[key]);
                return dict;
            }
var type = obj.GetType(); lock (dictionaryCache) { Func<object, Dictionary<string, object>> getter; if (dictionaryCache.TryGetValue(type, out getter) == false) { getter = CreateDictionaryGenerator(type); dictionaryCache[type] = getter; } var dict = getter(obj); return dict; } }

 

        private static Func<object, Dictionary<string, object>> CreateDictionaryGenerator(Type type)
        {
            var dm = new DynamicMethod((string.Format("Dictionary{0}", Guid.NewGuid())), typeof(Dictionary<string, object>), new[] { typeof(object) }, type, true);
            ILGenerator il = dm.GetILGenerator();
            il.DeclareLocal(typeof(Dictionary<string, object>));
            il.Emit(OpCodes.Nop);
            //Dictionary<string, object> dic = new Dictionary<string, object>();
            il.Emit(OpCodes.Newobj, typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0);

            foreach (var item in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                string columnName = item.Name;
                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ldstr, columnName);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Callvirt, item.GetGetMethod());
                if (item.PropertyType.IsValueType)
                {
                    il.Emit(OpCodes.Box, item.PropertyType);
                }
                il.Emit(OpCodes.Callvirt, typeof(Dictionary<string, object>).GetMethod("Add"));
            }
            il.Emit(OpCodes.Nop);

            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ret);
            var func = (Func<object, Dictionary<string, object>>)dm.CreateDelegate(typeof(Func<object, Dictionary<string, object>>));
            return func;
        }

 

推荐阅读