ReflectionUtil.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  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) where T : class
  31. {
  32. Type type = obj.GetType();
  33. var objReturn = type.InvokeMember(methodName, bf | BindingFlags.InvokeMethod, null, obj, args) as T;
  34. return objReturn;
  35. }
  36. /// <summary>
  37. /// 设置字段
  38. /// </summary>
  39. /// <param name="obj">反射对象</param>
  40. /// <param name="name">字段名</param>
  41. /// <param name="value">值</param>
  42. public static void SetField(this object obj, string name, object value)
  43. {
  44. FieldInfo fi = obj.GetType().GetField(name, bf);
  45. fi.SetValue(obj, value);
  46. }
  47. /// <summary>
  48. /// 获取字段
  49. /// </summary>
  50. /// <param name="obj">反射对象</param>
  51. /// <param name="name">字段名</param>
  52. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  53. /// <returns>T类型</returns>
  54. public static T GetField<T>(this object obj, string name) where T : class
  55. {
  56. FieldInfo fi = obj.GetType().GetField(name, bf);
  57. return fi.GetValue(obj) as T;
  58. }
  59. /// <summary>
  60. /// 获取所有的字段信息
  61. /// </summary>
  62. /// <param name="obj">反射对象</param>
  63. /// <returns>字段信息</returns>
  64. public static FieldInfo[] GetFields(this object obj)
  65. {
  66. FieldInfo[] fieldInfos = obj.GetType().GetFields(bf);
  67. return fieldInfos;
  68. }
  69. /// <summary>
  70. /// 设置属性
  71. /// </summary>
  72. /// <param name="obj">反射对象</param>
  73. /// <param name="name">属性名</param>
  74. /// <param name="value">值</param>
  75. public static void SetProperty(this object obj, string name, object value)
  76. {
  77. PropertyInfo fieldInfo = obj.GetType().GetProperty(name, bf);
  78. value = Convert.ChangeType(value, fieldInfo.PropertyType);
  79. fieldInfo.SetValue(obj, value, null);
  80. }
  81. /// <summary>
  82. /// 获取属性
  83. /// </summary>
  84. /// <param name="obj">反射对象</param>
  85. /// <param name="name">属性名</param>
  86. /// <typeparam name="T">约束返回的T必须是引用类型</typeparam>
  87. /// <returns>T类型</returns>
  88. public static T GetProperty<T>(this object obj, string name) where T : class
  89. {
  90. PropertyInfo fieldInfo = obj.GetType().GetProperty(name, bf);
  91. return fieldInfo.GetValue(obj, null) as T;
  92. }
  93. /// <summary>
  94. /// 获取所有的属性信息
  95. /// </summary>
  96. /// <param name="obj">反射对象</param>
  97. /// <returns>属性信息</returns>
  98. public static PropertyInfo[] GetProperties(this object obj)
  99. {
  100. PropertyInfo[] propertyInfos = obj.GetType().GetProperties(bf);
  101. return propertyInfos;
  102. }
  103. #endregion 属性字段设置
  104. #region 获取Description
  105. /// <summary>
  106. /// 获取枚举成员的Description信息
  107. /// </summary>
  108. /// <param name="value">枚举值</param>
  109. /// <returns>返回枚举的Description或ToString</returns>
  110. public static string GetDescription(this Enum value)
  111. {
  112. return GetDescription(value, null);
  113. }
  114. /// <summary>
  115. /// 获取枚举值的Description信息
  116. /// </summary>
  117. /// <param name ="value">枚举值</param>
  118. /// <param name ="args">要格式化的对象</param>
  119. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  120. public static string GetDescription(this Enum value, params object[] args)
  121. {
  122. if (value == null)
  123. {
  124. throw new ArgumentNullException(nameof(value));
  125. }
  126. FieldInfo fi = value.GetType().GetField(value.ToString());
  127. var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
  128. var text1 = attributes.Length > 0 ? attributes[0].Description : value.ToString();
  129. if ((args != null) && args.Length > 0)
  130. {
  131. return string.Format(null, text1, args);
  132. }
  133. return text1;
  134. }
  135. /// <summary>
  136. /// 根据成员信息获取Description信息
  137. /// </summary>
  138. /// <param name="member">成员信息</param>
  139. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  140. public static string GetDescription(this MemberInfo member)
  141. {
  142. return GetDescription(member, null);
  143. }
  144. /// <summary>
  145. /// 根据成员信息获取Description信息
  146. /// </summary>
  147. /// <param name="member">成员信息</param>
  148. /// <param name="args">格式化占位对象</param>
  149. /// <returns>如果未找到DescriptionAttribute则返回null或返回类型描述</returns>
  150. public static string GetDescription(this MemberInfo member, params object[] args)
  151. {
  152. string text1;
  153. if (member == null)
  154. {
  155. throw new ArgumentNullException(nameof(member));
  156. }
  157. if (member.IsDefined(typeof(DescriptionAttribute), false))
  158. {
  159. DescriptionAttribute[] attributes = (DescriptionAttribute[])member.GetCustomAttributes(typeof(DescriptionAttribute), false);
  160. text1 = attributes[0].Description;
  161. }
  162. else
  163. {
  164. return string.Empty;
  165. }
  166. if ((args != null) && (args.Length > 0))
  167. {
  168. return string.Format(null, text1, args);
  169. }
  170. return text1;
  171. }
  172. #endregion 获取Description
  173. #region 获取Attribute信息
  174. /// <summary>
  175. /// 获取对象的Attributes
  176. /// </summary>
  177. /// <param name="attributeType">Type类型</param>
  178. /// <param name="assembly">程序集信息</param>
  179. /// <returns></returns>
  180. public static object GetAttribute(this Type attributeType, Assembly assembly)
  181. {
  182. if (attributeType == null)
  183. {
  184. throw new ArgumentNullException(nameof(attributeType));
  185. }
  186. if (assembly == null)
  187. {
  188. throw new ArgumentNullException(nameof(assembly));
  189. }
  190. if (assembly.IsDefined(attributeType, false))
  191. {
  192. object[] attributes = assembly.GetCustomAttributes(attributeType, false);
  193. return attributes[0];
  194. }
  195. return null;
  196. }
  197. /// <summary>
  198. /// 获取对象的Attributes
  199. /// </summary>
  200. /// <param name="attributeType">Type类型</param>
  201. /// <param name="type">成员信息</param>
  202. /// <returns></returns>
  203. public static object GetAttribute(this Type attributeType, MemberInfo type)
  204. {
  205. return GetAttribute(attributeType, type, false);
  206. }
  207. /// <summary>
  208. /// 获取对象的Attributes
  209. /// </summary>
  210. /// <param name="attributeType">Type类型</param>
  211. /// <param name="type">成员信息</param>
  212. /// <param name="searchParent">是否在父类中去查找</param>
  213. /// <returns></returns>
  214. public static object GetAttribute(this Type attributeType, MemberInfo type, bool searchParent)
  215. {
  216. if (type == null)
  217. {
  218. return null;
  219. }
  220. if (!(attributeType.IsSubclassOf(typeof(Attribute))))
  221. {
  222. return null;
  223. }
  224. if (type.IsDefined(attributeType, searchParent))
  225. {
  226. object[] attributes = type.GetCustomAttributes(attributeType, searchParent);
  227. if (attributes.Length > 0)
  228. {
  229. return attributes[0];
  230. }
  231. }
  232. return null;
  233. }
  234. /// <summary>
  235. /// 获取对象的Attributes
  236. /// </summary>
  237. /// <param name="attributeType">Type类型</param>
  238. /// <param name="type">成员信息</param>
  239. /// <returns></returns>
  240. public static object[] GetAttributes(this Type attributeType, MemberInfo type)
  241. {
  242. return GetAttributes(attributeType, type, false);
  243. }
  244. /// <summary>
  245. /// 获取对象的Attributes
  246. /// </summary>
  247. /// <param name="attributeType">Type类型</param>
  248. /// <param name="type">成员信息</param>
  249. /// <param name="searchParent">是否在父类中去查找</param>
  250. /// <returns></returns>
  251. public static object[] GetAttributes(this Type attributeType, MemberInfo type, bool searchParent)
  252. {
  253. if (type == null)
  254. {
  255. return null;
  256. }
  257. if (!(attributeType.IsSubclassOf(typeof(Attribute))))
  258. {
  259. return null;
  260. }
  261. if (type.IsDefined(attributeType, false))
  262. {
  263. return type.GetCustomAttributes(attributeType, searchParent);
  264. }
  265. return null;
  266. }
  267. #endregion 获取Attribute信息
  268. #region 资源获取
  269. /// <summary>
  270. /// 根据资源名称获取图片资源流
  271. /// </summary>
  272. /// <param name="_"></param>
  273. /// <param name="resourceName">资源的名称</param>
  274. /// <returns>数据流</returns>
  275. public static Stream GetImageResource(this Assembly _, string resourceName)
  276. {
  277. Assembly asm = Assembly.GetExecutingAssembly();
  278. return asm.GetManifestResourceStream(resourceName);
  279. }
  280. /// <summary>
  281. /// 获取程序集资源的位图资源
  282. /// </summary>
  283. /// <param name="assemblyType">程序集中的某一对象类型</param>
  284. /// <param name="resourceHolder">资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。</param>
  285. /// <param name="imageName">资源项名称</param>
  286. public static Bitmap LoadBitmap(this Type assemblyType, string resourceHolder, string imageName)
  287. {
  288. Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
  289. ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
  290. return (Bitmap)rm.GetObject(imageName);
  291. }
  292. /// <summary>
  293. /// 获取程序集资源的文本资源
  294. /// </summary>
  295. /// <param name="assemblyType">程序集中的某一对象类型</param>
  296. /// <param name="resName">资源项名称</param>
  297. /// <param name="resourceHolder">资源的根名称。例如,名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。</param>
  298. public static string GetStringRes(this Type assemblyType, string resName, string resourceHolder)
  299. {
  300. Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
  301. ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
  302. return rm.GetString(resName);
  303. }
  304. /// <summary>
  305. /// 获取程序集嵌入资源的文本形式
  306. /// </summary>
  307. /// <param name="assemblyType">程序集中的某一对象类型</param>
  308. /// <param name="charset">字符集编码</param>
  309. /// <param name="resName">嵌入资源相对路径</param>
  310. /// <returns>如没找到该资源则返回空字符</returns>
  311. public static string GetManifestString(this Type assemblyType, string charset, string resName)
  312. {
  313. Assembly asm = Assembly.GetAssembly(assemblyType);
  314. Stream st = asm.GetManifestResourceStream(string.Concat(assemblyType.Namespace, ".", resName.Replace("/", ".")));
  315. if (st == null)
  316. {
  317. return "";
  318. }
  319. int iLen = (int)st.Length;
  320. byte[] bytes = new byte[iLen];
  321. st.Read(bytes, 0, iLen);
  322. return (bytes != null) ? Encoding.GetEncoding(charset).GetString(bytes) : "";
  323. }
  324. #endregion 资源获取
  325. #region 创建实例
  326. /// <summary>
  327. /// 获取默认实例
  328. /// </summary>
  329. /// <param name="type">类型</param>
  330. /// <returns></returns>
  331. public static object GetInstance(this Type type)
  332. {
  333. return GetInstance<TypeToIgnore, object>(type, null);
  334. }
  335. /// <summary>
  336. /// 获取默认实例
  337. /// </summary>
  338. /// <param name="type">类型</param>
  339. /// <returns></returns>
  340. public static T GetInstance<T>(this Type type) where T : class, new()
  341. {
  342. return GetInstance<TypeToIgnore, T>(type, null);
  343. }
  344. /// <summary>
  345. /// 获取默认实例
  346. /// </summary>
  347. /// <param name="type">类型</param>
  348. /// <returns></returns>
  349. public static T GetInstance<T>(string type) where T : class, new()
  350. {
  351. return GetInstance<TypeToIgnore, T>(Type.GetType(type), null);
  352. }
  353. /// <summary>
  354. /// 获取默认实例
  355. /// </summary>
  356. /// <param name="type">类型</param>
  357. /// <returns></returns>
  358. public static object GetInstance(string type)
  359. {
  360. return GetInstance<TypeToIgnore, object>(Type.GetType(type), null);
  361. }
  362. /// <summary>
  363. /// 获取一个构造参数的实例
  364. /// </summary>
  365. /// <typeparam name="TArg">参数类型</typeparam>
  366. /// <typeparam name="T"></typeparam>
  367. /// <param name="type">实例类型</param>
  368. /// <param name="argument">参数值</param>
  369. /// <returns></returns>
  370. public static T GetInstance<TArg, T>(this Type type, TArg argument) where T : class, new()
  371. {
  372. return GetInstance<TArg, TypeToIgnore, T>(type, argument, null);
  373. }
  374. /// <summary>
  375. /// 获取一个构造参数的实例
  376. /// </summary>
  377. /// <typeparam name="TArg">参数类型</typeparam>
  378. /// <typeparam name="T"></typeparam>
  379. /// <param name="type">实例类型</param>
  380. /// <param name="argument">参数值</param>
  381. /// <returns></returns>
  382. public static T GetInstance<TArg, T>(string type, TArg argument) where T : class, new()
  383. {
  384. return GetInstance<TArg, TypeToIgnore, T>(Type.GetType(type), argument, null);
  385. }
  386. /// <summary>
  387. /// 获取2个构造参数的实例
  388. /// </summary>
  389. /// <typeparam name="TArg1">参数类型</typeparam>
  390. /// <typeparam name="TArg2">参数类型</typeparam>
  391. /// <typeparam name="T"></typeparam>
  392. /// <param name="type">实例类型</param>
  393. /// <param name="argument1">参数值</param>
  394. /// <param name="argument2">参数值</param>
  395. /// <returns></returns>
  396. public static T GetInstance<TArg1, TArg2, T>(this Type type, TArg1 argument1, TArg2 argument2) where T : class, new()
  397. {
  398. return GetInstance<TArg1, TArg2, TypeToIgnore, T>(type, argument1, argument2, null);
  399. }
  400. /// <summary>
  401. /// 获取2个构造参数的实例
  402. /// </summary>
  403. /// <typeparam name="TArg1">参数类型</typeparam>
  404. /// <typeparam name="TArg2">参数类型</typeparam>
  405. /// <typeparam name="T"></typeparam>
  406. /// <param name="type">实例类型</param>
  407. /// <param name="argument1">参数值</param>
  408. /// <param name="argument2">参数值</param>
  409. /// <returns></returns>
  410. public static T GetInstance<TArg1, TArg2, T>(string type, TArg1 argument1, TArg2 argument2) where T : class, new()
  411. {
  412. return GetInstance<TArg1, TArg2, TypeToIgnore, T>(Type.GetType(type), argument1, argument2, null);
  413. }
  414. /// <summary>
  415. /// 获取3个构造参数的实例
  416. /// </summary>
  417. /// <typeparam name="TArg1">参数类型</typeparam>
  418. /// <typeparam name="TArg2">参数类型</typeparam>
  419. /// <typeparam name="TArg3">参数类型</typeparam>
  420. /// <typeparam name="T"></typeparam>
  421. /// <param name="type">实例类型</param>
  422. /// <param name="argument1">参数值</param>
  423. /// <param name="argument2">参数值</param>
  424. /// <param name="argument3">参数值</param>
  425. /// <returns></returns>
  426. public static T GetInstance<TArg1, TArg2, TArg3, T>(this Type type, TArg1 argument1, TArg2 argument2, TArg3 argument3) where T : class, new()
  427. {
  428. return InstanceCreationFactory<TArg1, TArg2, TArg3, T>.CreateInstanceOf(type, argument1, argument2, argument3);
  429. }
  430. /// <summary>
  431. /// 获取3个构造参数的实例
  432. /// </summary>
  433. /// <typeparam name="TArg1">参数类型</typeparam>
  434. /// <typeparam name="TArg2">参数类型</typeparam>
  435. /// <typeparam name="TArg3">参数类型</typeparam>
  436. /// <typeparam name="T"></typeparam>
  437. /// <param name="type">实例类型</param>
  438. /// <param name="argument1">参数值</param>
  439. /// <param name="argument2">参数值</param>
  440. /// <param name="argument3">参数值</param>
  441. /// <returns></returns>
  442. public static T GetInstance<TArg1, TArg2, TArg3, T>(string type, TArg1 argument1, TArg2 argument2, TArg3 argument3) where T : class, new()
  443. {
  444. return InstanceCreationFactory<TArg1, TArg2, TArg3, T>.CreateInstanceOf(Type.GetType(type), argument1, argument2, argument3);
  445. }
  446. private class TypeToIgnore
  447. {
  448. }
  449. private static class InstanceCreationFactory<TArg1, TArg2, TArg3, TObject> where TObject : class, new()
  450. {
  451. private static readonly Dictionary<Type, Func<TArg1, TArg2, TArg3, TObject>> InstanceCreationMethods = new Dictionary<Type, Func<TArg1, TArg2, TArg3, TObject>>();
  452. public static TObject CreateInstanceOf(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
  453. {
  454. CacheInstanceCreationMethodIfRequired(type);
  455. return InstanceCreationMethods[type](arg1, arg2, arg3);
  456. }
  457. private static void CacheInstanceCreationMethodIfRequired(Type type)
  458. {
  459. if (InstanceCreationMethods.ContainsKey(type))
  460. {
  461. return;
  462. }
  463. var argumentTypes = new[]
  464. {
  465. typeof(TArg1),
  466. typeof(TArg2),
  467. typeof(TArg3)
  468. };
  469. Type[] constructorArgumentTypes = argumentTypes.Where(t => t != typeof(TypeToIgnore)).ToArray();
  470. var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, constructorArgumentTypes, Array.Empty<ParameterModifier>());
  471. var lamdaParameterExpressions = new[]
  472. {
  473. Expression.Parameter(typeof(TArg1), "param1"),
  474. Expression.Parameter(typeof(TArg2), "param2"),
  475. Expression.Parameter(typeof(TArg3), "param3")
  476. };
  477. var constructorParameterExpressions = lamdaParameterExpressions.Take(constructorArgumentTypes.Length).ToArray();
  478. var constructorCallExpression = Expression.New(constructor, constructorParameterExpressions);
  479. var constructorCallingLambda = Expression.Lambda<Func<TArg1, TArg2, TArg3, TObject>>(constructorCallExpression, lamdaParameterExpressions).Compile();
  480. InstanceCreationMethods[type] = constructorCallingLambda;
  481. }
  482. }
  483. #endregion 创建实例
  484. }
  485. }