ReflectionUtil.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Linq.Expressions;
  8. using System.Reflection;
  9. using System.Resources;
  10. using System.Text;
  11. namespace Masuit.Tools.Reflection
  12. {
  13. /// <summary>
  14. /// 反射操作辅助类,如获取或设置字段、属性的值等反射信息。
  15. /// </summary>
  16. public static class ReflectionUtil
  17. {
  18. #region 属性字段设置
  19. #pragma warning disable 1591
  20. public static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
  21. #pragma warning restore 1591
  22. /// <summary>
  23. /// 执行方法
  24. /// </summary>
  25. /// <param name="obj">反射对象</param>
  26. /// <param name="methodName">方法名,区分大小写</param>
  27. /// <param name="args">方法参数</param>
  28. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  29. /// <returns>T类型</returns>
  30. public static T InvokeMethod<T>(this object obj, string methodName, object[] args)
  31. {
  32. var type = obj.GetType();
  33. var parameter = Expression.Parameter(type, "e");
  34. var callExpression = Expression.Call(parameter, type.GetMethod(methodName, args.Select(o => o.GetType()).ToArray()), args.Select(Expression.Constant));
  35. return (T)Expression.Lambda(callExpression, parameter).Compile().DynamicInvoke(obj);
  36. }
  37. /// <summary>
  38. /// 执行方法
  39. /// </summary>
  40. /// <param name="obj">反射对象</param>
  41. /// <param name="methodName">方法名,区分大小写</param>
  42. /// <param name="args">方法参数</param>
  43. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  44. /// <returns>T类型</returns>
  45. public static void InvokeMethod(this object obj, string methodName, object[] args)
  46. {
  47. var type = obj.GetType();
  48. var parameter = Expression.Parameter(type, "e");
  49. var callExpression = Expression.Call(parameter, type.GetMethod(methodName, args.Select(o => o.GetType()).ToArray()), args.Select(Expression.Constant));
  50. Expression.Lambda(callExpression, parameter).Compile().DynamicInvoke(obj);
  51. }
  52. /// <summary>
  53. /// 设置字段
  54. /// </summary>
  55. /// <param name="obj">反射对象</param>
  56. /// <param name="name">字段名</param>
  57. /// <param name="value">值</param>
  58. public static void SetField<T>(this T obj, string name, object value) where T : class
  59. {
  60. SetProperty(obj, name, value);
  61. }
  62. /// <summary>
  63. /// 获取字段
  64. /// </summary>
  65. /// <param name="obj">反射对象</param>
  66. /// <param name="name">字段名</param>
  67. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  68. /// <returns>T类型</returns>
  69. public static T GetField<T>(this object obj, string name)
  70. {
  71. return GetProperty<T>(obj, name);
  72. }
  73. /// <summary>
  74. /// 获取所有的字段信息
  75. /// </summary>
  76. /// <param name="obj">反射对象</param>
  77. /// <returns>字段信息</returns>
  78. public static FieldInfo[] GetFields(this object obj)
  79. {
  80. FieldInfo[] fieldInfos = obj.GetType().GetFields(bf);
  81. return fieldInfos;
  82. }
  83. /// <summary>
  84. /// 设置属性
  85. /// </summary>
  86. /// <param name="obj">反射对象</param>
  87. /// <param name="name">属性名</param>
  88. /// <param name="value">值</param>
  89. public static string SetProperty<T>(this T obj, string name, object value) where T : class
  90. {
  91. var parameter = Expression.Parameter(typeof(T), "e");
  92. var property = Expression.PropertyOrField(parameter, name);
  93. var before = Expression.Lambda(property, parameter).Compile().DynamicInvoke(obj).ToJsonString();
  94. if (property.Type.GetGenericTypeDefinition() == typeof(Nullable<>))
  95. {
  96. typeof(T).GetProperty(name)?.SetValue(obj, value);
  97. }
  98. else
  99. {
  100. var assign = Expression.Assign(property, Expression.Constant(value));
  101. Expression.Lambda(assign, parameter).Compile().DynamicInvoke(obj);
  102. }
  103. return before;
  104. }
  105. /// <summary>
  106. /// 获取属性
  107. /// </summary>
  108. /// <param name="obj">反射对象</param>
  109. /// <param name="name">属性名</param>
  110. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  111. /// <returns>T类型</returns>
  112. public static T GetProperty<T>(this object obj, string name)
  113. {
  114. var parameter = Expression.Parameter(obj.GetType(), "e");
  115. var property = Expression.PropertyOrField(parameter, name);
  116. return (T)Expression.Lambda(property, parameter).Compile().DynamicInvoke(obj);
  117. }
  118. /// <summary>
  119. /// 获取所有的属性信息
  120. /// </summary>
  121. /// <param name="obj">反射对象</param>
  122. /// <returns>属性信息</returns>
  123. public static PropertyInfo[] GetProperties(this object obj)
  124. {
  125. PropertyInfo[] propertyInfos = obj.GetType().GetProperties(bf);
  126. return propertyInfos;
  127. }
  128. #endregion 属性字段设置
  129. #region 获取Description
  130. /// <summary>
  131. /// 获取枚举成员的Description信息
  132. /// </summary>
  133. /// <param name="value">枚举值</param>
  134. /// <returns>返回枚举的Description或ToString</returns>
  135. public static string GetDescription(this Enum value)
  136. {
  137. return GetDescription(value, null);
  138. }
  139. /// <summary>
  140. /// 获取枚举值的Description信息
  141. /// </summary>
  142. /// <param name ="value">枚举值</param>
  143. /// <param name ="args">要格式化的对象</param>
  144. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  145. public static string GetDescription(this Enum value, params object[] args)
  146. {
  147. if (value == null)
  148. {
  149. throw new ArgumentNullException(nameof(value));
  150. }
  151. FieldInfo fi = value.GetType().GetField(value.ToString());
  152. var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
  153. var text = attributes.Length > 0 ? attributes[0].Description : value.ToString();
  154. if ((args != null) && args.Length > 0)
  155. {
  156. return string.Format(null, text, args);
  157. }
  158. return text;
  159. }
  160. /// <summary>
  161. /// 根据成员信息获取Description信息
  162. /// </summary>
  163. /// <param name="member">成员信息</param>
  164. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  165. public static string GetDescription(this MemberInfo member)
  166. {
  167. return GetDescription(member, null);
  168. }
  169. /// <summary>
  170. /// 根据成员信息获取Description信息
  171. /// </summary>
  172. /// <param name="member">成员信息</param>
  173. /// <param name="args">格式化占位对象</param>
  174. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  175. public static string GetDescription(this MemberInfo member, params object[] args)
  176. {
  177. if (member == null)
  178. {
  179. throw new ArgumentNullException(nameof(member));
  180. }
  181. return member.IsDefined(typeof(DescriptionAttribute), false) ? member.GetAttribute<DescriptionAttribute>().Description : string.Empty;
  182. }
  183. #endregion 获取Description
  184. /// <summary>
  185. /// 获取对象的Attribute
  186. /// </summary>
  187. /// <returns></returns>
  188. public static T GetAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute
  189. {
  190. var attributes = provider.GetCustomAttributes(typeof(T), true);
  191. return attributes.Length > 0 ? attributes[0] as T : null;
  192. }
  193. #region 资源获取
  194. /// <summary>
  195. /// 根据资源名称获取图片资源流
  196. /// </summary>
  197. /// <param name="_"></param>
  198. /// <param name="resourceName">资源的名称</param>
  199. /// <returns>数据流</returns>
  200. public static Stream GetImageResource(this Assembly _, string resourceName)
  201. {
  202. Assembly asm = Assembly.GetExecutingAssembly();
  203. return asm.GetManifestResourceStream(resourceName);
  204. }
  205. /// <summary>
  206. /// 获取程序集资源的位图资源
  207. /// </summary>
  208. /// <param name="assemblyType">程序集中的某一对象类型</param>
  209. /// <param name="resourceHolder">资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。</param>
  210. /// <param name="imageName">资源项名称</param>
  211. public static Bitmap LoadBitmap(this Type assemblyType, string resourceHolder, string imageName)
  212. {
  213. Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
  214. ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
  215. return (Bitmap)rm.GetObject(imageName);
  216. }
  217. /// <summary>
  218. /// 获取程序集资源的文本资源
  219. /// </summary>
  220. /// <param name="assemblyType">程序集中的某一对象类型</param>
  221. /// <param name="resName">资源项名称</param>
  222. /// <param name="resourceHolder">资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。</param>
  223. public static string GetStringRes(this Type assemblyType, string resName, string resourceHolder)
  224. {
  225. Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
  226. ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
  227. return rm.GetString(resName);
  228. }
  229. /// <summary>
  230. /// 获取程序集嵌入资源的文本形式
  231. /// </summary>
  232. /// <param name="assemblyType">程序集中的某一对象类型</param>
  233. /// <param name="charset">字符集编码</param>
  234. /// <param name="resName">嵌入资源相对路径</param>
  235. /// <returns>如没找到该资源则返回空字符</returns>
  236. public static string GetManifestString(this Type assemblyType, string charset, string resName)
  237. {
  238. Assembly asm = Assembly.GetAssembly(assemblyType);
  239. Stream st = asm.GetManifestResourceStream(string.Concat(assemblyType.Namespace, ".", resName.Replace("/", ".")));
  240. if (st == null)
  241. {
  242. return "";
  243. }
  244. int iLen = (int)st.Length;
  245. byte[] bytes = new byte[iLen];
  246. st.Read(bytes, 0, iLen);
  247. return (bytes != null) ? Encoding.GetEncoding(charset).GetString(bytes) : "";
  248. }
  249. #endregion 资源获取
  250. #region 创建实例
  251. /// <summary>
  252. /// 获取默认实例
  253. /// </summary>
  254. /// <param name="type">类型</param>
  255. /// <returns></returns>
  256. public static object GetInstance(this Type type)
  257. {
  258. return GetInstance<TypeToIgnore, object>(type, null);
  259. }
  260. /// <summary>
  261. /// 获取默认实例
  262. /// </summary>
  263. /// <param name="type">类型</param>
  264. /// <returns></returns>
  265. public static T GetInstance<T>(this Type type) where T : class, new()
  266. {
  267. return GetInstance<TypeToIgnore, T>(type, null);
  268. }
  269. /// <summary>
  270. /// 获取默认实例
  271. /// </summary>
  272. /// <param name="type">类型</param>
  273. /// <returns></returns>
  274. public static T GetInstance<T>(string type) where T : class, new()
  275. {
  276. return GetInstance<TypeToIgnore, T>(Type.GetType(type), null);
  277. }
  278. /// <summary>
  279. /// 获取默认实例
  280. /// </summary>
  281. /// <param name="type">类型</param>
  282. /// <returns></returns>
  283. public static object GetInstance(string type)
  284. {
  285. return GetInstance<TypeToIgnore, object>(Type.GetType(type), null);
  286. }
  287. /// <summary>
  288. /// 获取一个构造参数的实例
  289. /// </summary>
  290. /// <typeparam name="TArg">参数类型</typeparam>
  291. /// <typeparam name="T"></typeparam>
  292. /// <param name="type">实例类型</param>
  293. /// <param name="argument">参数值</param>
  294. /// <returns></returns>
  295. public static T GetInstance<TArg, T>(this Type type, TArg argument) where T : class, new()
  296. {
  297. return GetInstance<TArg, TypeToIgnore, T>(type, argument, null);
  298. }
  299. /// <summary>
  300. /// 获取一个构造参数的实例
  301. /// </summary>
  302. /// <typeparam name="TArg">参数类型</typeparam>
  303. /// <typeparam name="T"></typeparam>
  304. /// <param name="type">实例类型</param>
  305. /// <param name="argument">参数值</param>
  306. /// <returns></returns>
  307. public static T GetInstance<TArg, T>(string type, TArg argument) where T : class, new()
  308. {
  309. return GetInstance<TArg, TypeToIgnore, T>(Type.GetType(type), argument, null);
  310. }
  311. /// <summary>
  312. /// 获取2个构造参数的实例
  313. /// </summary>
  314. /// <typeparam name="TArg1">参数类型</typeparam>
  315. /// <typeparam name="TArg2">参数类型</typeparam>
  316. /// <typeparam name="T"></typeparam>
  317. /// <param name="type">实例类型</param>
  318. /// <param name="argument1">参数值</param>
  319. /// <param name="argument2">参数值</param>
  320. /// <returns></returns>
  321. public static T GetInstance<TArg1, TArg2, T>(this Type type, TArg1 argument1, TArg2 argument2) where T : class, new()
  322. {
  323. return GetInstance<TArg1, TArg2, TypeToIgnore, T>(type, argument1, argument2, null);
  324. }
  325. /// <summary>
  326. /// 获取2个构造参数的实例
  327. /// </summary>
  328. /// <typeparam name="TArg1">参数类型</typeparam>
  329. /// <typeparam name="TArg2">参数类型</typeparam>
  330. /// <typeparam name="T"></typeparam>
  331. /// <param name="type">实例类型</param>
  332. /// <param name="argument1">参数值</param>
  333. /// <param name="argument2">参数值</param>
  334. /// <returns></returns>
  335. public static T GetInstance<TArg1, TArg2, T>(string type, TArg1 argument1, TArg2 argument2) where T : class, new()
  336. {
  337. return GetInstance<TArg1, TArg2, TypeToIgnore, T>(Type.GetType(type), argument1, argument2, null);
  338. }
  339. /// <summary>
  340. /// 获取3个构造参数的实例
  341. /// </summary>
  342. /// <typeparam name="TArg1">参数类型</typeparam>
  343. /// <typeparam name="TArg2">参数类型</typeparam>
  344. /// <typeparam name="TArg3">参数类型</typeparam>
  345. /// <typeparam name="T"></typeparam>
  346. /// <param name="type">实例类型</param>
  347. /// <param name="argument1">参数值</param>
  348. /// <param name="argument2">参数值</param>
  349. /// <param name="argument3">参数值</param>
  350. /// <returns></returns>
  351. public static T GetInstance<TArg1, TArg2, TArg3, T>(this Type type, TArg1 argument1, TArg2 argument2, TArg3 argument3) where T : class, new()
  352. {
  353. return InstanceCreationFactory<TArg1, TArg2, TArg3, T>.CreateInstanceOf(type, argument1, argument2, argument3);
  354. }
  355. /// <summary>
  356. /// 获取3个构造参数的实例
  357. /// </summary>
  358. /// <typeparam name="TArg1">参数类型</typeparam>
  359. /// <typeparam name="TArg2">参数类型</typeparam>
  360. /// <typeparam name="TArg3">参数类型</typeparam>
  361. /// <typeparam name="T"></typeparam>
  362. /// <param name="type">实例类型</param>
  363. /// <param name="argument1">参数值</param>
  364. /// <param name="argument2">参数值</param>
  365. /// <param name="argument3">参数值</param>
  366. /// <returns></returns>
  367. public static T GetInstance<TArg1, TArg2, TArg3, T>(string type, TArg1 argument1, TArg2 argument2, TArg3 argument3) where T : class, new()
  368. {
  369. return InstanceCreationFactory<TArg1, TArg2, TArg3, T>.CreateInstanceOf(Type.GetType(type), argument1, argument2, argument3);
  370. }
  371. private class TypeToIgnore
  372. {
  373. }
  374. private static class InstanceCreationFactory<TArg1, TArg2, TArg3, TObject> where TObject : class, new()
  375. {
  376. private static readonly Dictionary<Type, Func<TArg1, TArg2, TArg3, TObject>> InstanceCreationMethods = new Dictionary<Type, Func<TArg1, TArg2, TArg3, TObject>>();
  377. public static TObject CreateInstanceOf(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
  378. {
  379. CacheInstanceCreationMethodIfRequired(type);
  380. return InstanceCreationMethods[type](arg1, arg2, arg3);
  381. }
  382. private static void CacheInstanceCreationMethodIfRequired(Type type)
  383. {
  384. if (InstanceCreationMethods.ContainsKey(type))
  385. {
  386. return;
  387. }
  388. var argumentTypes = new[]
  389. {
  390. typeof(TArg1),
  391. typeof(TArg2),
  392. typeof(TArg3)
  393. };
  394. Type[] constructorArgumentTypes = argumentTypes.Where(t => t != typeof(TypeToIgnore)).ToArray();
  395. var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, constructorArgumentTypes, Array.Empty<ParameterModifier>());
  396. var lamdaParameterExpressions = new[]
  397. {
  398. Expression.Parameter(typeof(TArg1), "param1"),
  399. Expression.Parameter(typeof(TArg2), "param2"),
  400. Expression.Parameter(typeof(TArg3), "param3")
  401. };
  402. var constructorParameterExpressions = lamdaParameterExpressions.Take(constructorArgumentTypes.Length).ToArray();
  403. var constructorCallExpression = Expression.New(constructor, constructorParameterExpressions);
  404. var constructorCallingLambda = Expression.Lambda<Func<TArg1, TArg2, TArg3, TObject>>(constructorCallExpression, lamdaParameterExpressions).Compile();
  405. InstanceCreationMethods[type] = constructorCallingLambda;
  406. }
  407. }
  408. #endregion 创建实例
  409. }
  410. }