如果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; }