ExpandoUtils.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.ComponentModel;
  5. using System.Dynamic;
  6. using System.Globalization;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace JiaZhiQuan.Common.Utils {
  12. public class ExpandoUtils {
  13. /// <summary>
  14. /// 转成可以扩充的对象
  15. /// </summary> www.it165.net
  16. /// <param name="obj"></param>
  17. /// <returns></returns>
  18. public static dynamic ConvertToDynamic(object obj) {
  19. IDictionary<string, object> result = new ExpandoObject();
  20. if(obj is IDictionary<string, object> rst) {
  21. foreach (var item in rst) {
  22. result.Add(item.Key, item.Value);
  23. }
  24. return result;
  25. }
  26. foreach (PropertyDescriptor pro in TypeDescriptor.GetProperties(obj.GetType())) {
  27. result.Add(pro.Name, pro.GetValue(obj));
  28. }
  29. return result;
  30. }
  31. public static List<dynamic> ConvertToListDynamic<S>(List<S> list) {
  32. if (list == null || list.Count == 0) return new List<dynamic>();
  33. return (from obj in list
  34. where obj != null
  35. select ConvertToDynamic(obj)).ToList();
  36. }
  37. public static T DictToObject<T>(IDictionary<string, object> dict,string dateFormat=null) {
  38. var type = typeof(T);
  39. var obj = Activator.CreateInstance(type);
  40. if (dict == null) return (T)obj;
  41. var properties = type.GetProperties();
  42. foreach (var item in properties) {
  43. if (!dict.ContainsKey(item.Name)) continue;
  44. var value = dict[item.Name]?.ToString();
  45. if(value==null) continue;
  46. var propertyType = item.PropertyType;
  47. if (propertyType.IsEnum) {
  48. item.SetValue(obj, Enum.Parse(propertyType, value));
  49. } else if (propertyType.IsGenericType) {
  50. propertyType = propertyType.GenericTypeArguments[0];
  51. if (propertyType.IsEnum) {
  52. item.SetValue(obj, Enum.Parse(propertyType, value));
  53. }
  54. } else if (propertyType ==typeof( DateTime)) {
  55. if(dateFormat==null) {
  56. dateFormat = "yyyy-MM-dd HH:mm:ss";
  57. }
  58. item.SetValue(obj, DateTime.ParseExact(value, dateFormat, CultureInfo.CurrentCulture));
  59. }
  60. else {
  61. item.SetValue(obj, Convert.ChangeType(value, propertyType));
  62. }
  63. }
  64. return (T)obj;
  65. }
  66. public class MyDynamic : DynamicObject {
  67. // The inner dictionary.
  68. Dictionary<string, object> dictionary = new Dictionary<string, object>();
  69. // This property returns the number of elements
  70. // in the inner dictionary.
  71. public int Count {
  72. get {
  73. return dictionary.Count;
  74. }
  75. }
  76. // If you try to get a value of a property
  77. // not defined in the class, this method is called.
  78. public override bool TryGetMember(
  79. GetMemberBinder binder, out object? result) {
  80. // Converting the property name to lowercase
  81. // so that property names become case-insensitive.
  82. string name = binder.Name.ToLower();
  83. // If the property name is found in a dictionary,
  84. // set the result parameter to the property value and return true.
  85. // Otherwise, return false.
  86. return dictionary.TryGetValue(name, out result);
  87. }
  88. // If you try to set a value of a property that is
  89. // not defined in the class, this method is called.
  90. public override bool TrySetMember(
  91. SetMemberBinder binder, object? value) {
  92. // Converting the property name to lowercase
  93. // so that property names become case-insensitive.
  94. dictionary[binder.Name.ToLower()] = value!;
  95. // You can always add a value to a dictionary,
  96. // so this method always returns true.
  97. return true;
  98. }
  99. public override bool TryInvokeMember(InvokeMemberBinder binder, object?[]? args, out object? result) {
  100. Type dictType = typeof(Dictionary<string, object>);
  101. try {
  102. result = dictType.InvokeMember(binder.Name,BindingFlags.InvokeMethod,
  103. null, dictionary, args);
  104. return true;
  105. } catch {
  106. result = null;
  107. return false;
  108. }
  109. }
  110. }
  111. }
  112. }