123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Xml.Serialization;
- internal class Reflection
- {
- internal delegate object GenericSetter(object target, object value);
- internal delegate object GenericGetter(object obj);
- private delegate object CreateObject();
- public static readonly Reflection Instance = new Reflection();
- public bool ShowReadOnlyProperties = false;
- private SafeDictionary<Type, string> _tyname = new SafeDictionary<Type, string>();
- private SafeDictionary<string, Type> _typecache = new SafeDictionary<string, Type>();
- private SafeDictionary<Type, CreateObject> _constrcache = new SafeDictionary<Type, CreateObject>();
- private SafeDictionary<Type, List<Getters>> _getterscache = new SafeDictionary<Type, List<Getters>>();
- private Reflection()
- {
- }
- internal string GetTypeAssemblyName(Type t)
- {
- string val = "";
- if (_tyname.TryGetValue(t, out val))
- {
- return val;
- }
- string s = t.AssemblyQualifiedName;
- _tyname.Add(t, s);
- return s;
- }
- internal Type GetTypeFromCache(string typename)
- {
- Type val = null;
- if (_typecache.TryGetValue(typename, out val))
- {
- return val;
- }
- Type t = Type.GetType(typename);
- _typecache.Add(typename, t);
- return t;
- }
- internal object FastCreateInstance(Type objtype)
- {
- try
- {
- CreateObject c = null;
- if (_constrcache.TryGetValue(objtype, out c))
- {
- return c();
- }
- DynamicMethod dynMethod = new DynamicMethod("_", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(object), null, objtype, skipVisibility: false);
- ILGenerator ilGen = dynMethod.GetILGenerator();
- if (objtype.IsClass)
- {
- ilGen.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes));
- ilGen.Emit(OpCodes.Ret);
- c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
- _constrcache.Add(objtype, c);
- }
- else
- {
- LocalBuilder lv = ilGen.DeclareLocal(objtype);
- ilGen.Emit(OpCodes.Ldloca_S, lv);
- ilGen.Emit(OpCodes.Initobj, objtype);
- ilGen.Emit(OpCodes.Ldloc_0);
- ilGen.Emit(OpCodes.Box, objtype);
- ilGen.Emit(OpCodes.Ret);
- c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
- _constrcache.Add(objtype, c);
- }
- return c();
- }
- catch (Exception exc)
- {
- throw new Exception($"Failed to fast create instance for type '{objtype.FullName}' from assemebly '{objtype.AssemblyQualifiedName}'", exc);
- }
- }
- internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo)
- {
- Type[] arguments = new Type[2];
- arguments[0] = (arguments[1] = typeof(object));
- DynamicMethod dynamicSet = new DynamicMethod("_", typeof(object), arguments, type, skipVisibility: true);
- ILGenerator il = dynamicSet.GetILGenerator();
- if (!type.IsClass)
- {
- LocalBuilder lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldarg_1);
- if (fieldInfo.FieldType.IsClass)
- {
- il.Emit(OpCodes.Castclass, fieldInfo.FieldType);
- }
- else
- {
- il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
- }
- il.Emit(OpCodes.Stfld, fieldInfo);
- il.Emit(OpCodes.Ldloc_0);
- il.Emit(OpCodes.Box, type);
- il.Emit(OpCodes.Ret);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldarg_1);
- if (fieldInfo.FieldType.IsValueType)
- {
- il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
- }
- il.Emit(OpCodes.Stfld, fieldInfo);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ret);
- }
- return (GenericSetter)dynamicSet.CreateDelegate(typeof(GenericSetter));
- }
- internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo)
- {
- MethodInfo setMethod = propertyInfo.GetSetMethod();
- if (setMethod == null)
- {
- return null;
- }
- Type[] arguments = new Type[2];
- arguments[0] = (arguments[1] = typeof(object));
- DynamicMethod setter = new DynamicMethod("_", typeof(object), arguments, type);
- ILGenerator il = setter.GetILGenerator();
- if (!type.IsClass)
- {
- LocalBuilder lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldarg_1);
- if (propertyInfo.PropertyType.IsClass)
- {
- il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
- }
- else
- {
- il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
- }
- il.EmitCall(OpCodes.Call, setMethod, null);
- il.Emit(OpCodes.Ldloc_0);
- il.Emit(OpCodes.Box, type);
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
- il.Emit(OpCodes.Ldarg_1);
- if (propertyInfo.PropertyType.IsClass)
- {
- il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
- }
- else
- {
- il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
- }
- il.EmitCall(OpCodes.Callvirt, setMethod, null);
- il.Emit(OpCodes.Ldarg_0);
- }
- il.Emit(OpCodes.Ret);
- return (GenericSetter)setter.CreateDelegate(typeof(GenericSetter));
- }
- internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo)
- {
- DynamicMethod dynamicGet = new DynamicMethod("_", typeof(object), new Type[1] { typeof(object) }, type, skipVisibility: true);
- ILGenerator il = dynamicGet.GetILGenerator();
- if (!type.IsClass)
- {
- LocalBuilder lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.Emit(OpCodes.Ldfld, fieldInfo);
- if (fieldInfo.FieldType.IsValueType)
- {
- il.Emit(OpCodes.Box, fieldInfo.FieldType);
- }
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldfld, fieldInfo);
- if (fieldInfo.FieldType.IsValueType)
- {
- il.Emit(OpCodes.Box, fieldInfo.FieldType);
- }
- }
- il.Emit(OpCodes.Ret);
- return (GenericGetter)dynamicGet.CreateDelegate(typeof(GenericGetter));
- }
- internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyInfo)
- {
- MethodInfo getMethod = propertyInfo.GetGetMethod();
- if (getMethod == null)
- {
- return null;
- }
- DynamicMethod getter = new DynamicMethod(parameterTypes: new Type[1] { typeof(object) }, name: "_", returnType: typeof(object), owner: type);
- ILGenerator il = getter.GetILGenerator();
- if (!type.IsClass)
- {
- LocalBuilder lv = il.DeclareLocal(type);
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Unbox_Any, type);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloca_S, lv);
- il.EmitCall(OpCodes.Call, getMethod, null);
- if (propertyInfo.PropertyType.IsValueType)
- {
- il.Emit(OpCodes.Box, propertyInfo.PropertyType);
- }
- }
- else
- {
- il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
- il.EmitCall(OpCodes.Callvirt, getMethod, null);
- if (propertyInfo.PropertyType.IsValueType)
- {
- il.Emit(OpCodes.Box, propertyInfo.PropertyType);
- }
- }
- il.Emit(OpCodes.Ret);
- return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter));
- }
- internal List<Getters> GetGetters(Type type)
- {
- List<Getters> val = null;
- if (_getterscache.TryGetValue(type, out val))
- {
- return val;
- }
- PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
- List<Getters> getters = new List<Getters>();
- PropertyInfo[] array = props;
- foreach (PropertyInfo p in array)
- {
- if (!p.CanWrite && !ShowReadOnlyProperties)
- {
- continue;
- }
- object[] att = p.GetCustomAttributes(typeof(XmlIgnoreAttribute), inherit: false);
- if (att == null || att.Length == 0)
- {
- GenericGetter g = CreateGetMethod(type, p);
- if (g != null)
- {
- Getters gg = new Getters();
- gg.Name = p.Name;
- gg.Getter = g;
- gg.propertyType = p.PropertyType;
- getters.Add(gg);
- }
- }
- }
- FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
- FieldInfo[] array2 = fi;
- foreach (FieldInfo f in array2)
- {
- object[] att2 = f.GetCustomAttributes(typeof(XmlIgnoreAttribute), inherit: false);
- if (att2 == null || att2.Length == 0)
- {
- GenericGetter g2 = CreateGetField(type, f);
- if (g2 != null)
- {
- Getters gg2 = new Getters();
- gg2.Name = f.Name;
- gg2.Getter = g2;
- gg2.propertyType = f.FieldType;
- getters.Add(gg2);
- }
- }
- }
- _getterscache.Add(type, getters);
- return getters;
- }
- }
|