You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.3 KiB

4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using static Apewer.TextUtility;
  4. #if !NET20
  5. using System.Dynamic;
  6. #endif
  7. namespace Apewer
  8. {
  9. /// <summary>对象字典模型。</summary>
  10. [Serializable]
  11. public class ObjectSet : ObjectSet<object>
  12. {
  13. /// <summary>构造函数。</summary>
  14. /// <param name="dictionary">引用指定的字典,指定 NULL 时创建新字典。</param>
  15. /// <param name="always">对动态属性的访问始终返回 TRUE 值。</param>
  16. public ObjectSet(Dictionary<string, object> dictionary, bool always = false) : base(dictionary, always) { }
  17. /// <summary></summary>
  18. /// <param name="trimKey">使用 get 和 set 访问器时候修建 Key。</param>
  19. /// <param name="always">对动态属性的访问始终返回 TRUE 值。</param>
  20. public ObjectSet(bool trimKey = false, bool always = false) : base(trimKey, always) { }
  21. }
  22. /// <summary>字典模型。</summary>
  23. [Serializable]
  24. public partial class ObjectSet<T> : IToJson
  25. {
  26. private Dictionary<string, T> _origin;
  27. private bool _trimkey = false;
  28. private bool _locked = false;
  29. internal bool _always = false;
  30. /// <summary>获取或设置字典内容。</summary>
  31. public T this[string key] { get { return Get(key); } set { Set(key, value); } }
  32. /// <summary>获取字典。</summary>
  33. internal Dictionary<string, T> Origin { get { return _origin; } }
  34. internal bool Locked { get { return _locked; } set { _locked = value; } }
  35. internal bool TrimKey { get { return _trimkey; } set { _trimkey = value; } }
  36. /// <summary>构造函数。</summary>
  37. /// <param name="dictionary">引用指定的字典,指定 NULL 时创建新字典。</param>
  38. /// <param name="always">对动态属性的访问始终返回 TRUE 值。</param>
  39. public ObjectSet(Dictionary<string, T> dictionary, bool always = false)
  40. {
  41. _trimkey = false;
  42. _always = always;
  43. _origin = dictionary ?? new Dictionary<string, T>();
  44. }
  45. /// <summary>构造函数。</summary>
  46. /// <param name="trimKey">使用 get 和 set 访问器时候修建 Key。</param>
  47. /// <param name="always">对动态属性的访问始终返回 TRUE 值。</param>
  48. public ObjectSet(bool trimKey = false, bool always = false)
  49. {
  50. _trimkey = trimKey;
  51. _always = always;
  52. _origin = new Dictionary<string, T>();
  53. }
  54. private T Get(string key)
  55. {
  56. var contains = false;
  57. return Get(key, ref contains);
  58. }
  59. private T Get(string key, ref bool contains)
  60. {
  61. var value = default(T);
  62. if (key != null)
  63. {
  64. var k = _trimkey ? Trim(key) : key;
  65. lock (_origin)
  66. {
  67. contains = _origin.ContainsKey(k);
  68. if (contains) value = _origin[k];
  69. }
  70. }
  71. return value;
  72. }
  73. private bool Set(string key, T value)
  74. {
  75. if (_locked) return false;
  76. var success = false;
  77. if (key != null)
  78. {
  79. var k = _trimkey ? Trim(key) : key;
  80. lock (_origin)
  81. {
  82. if (_origin.ContainsKey(k)) _origin[k] = value;
  83. else _origin.Add(k, value);
  84. success = true;
  85. }
  86. }
  87. return success;
  88. }
  89. /// <summary>转换为 <see cref="Json"/> 对象。</summary>
  90. public Json ToJson() => Json.From(_origin);
  91. /// <summary>转换为 <see cref="Json"/> 字符串。</summary>
  92. public override string ToString()
  93. {
  94. var json = ToJson();
  95. if (json == null) return null;
  96. return json.ToString(true);
  97. }
  98. }
  99. #if !NET20
  100. /// <summary>字典模型。</summary>
  101. public partial class ObjectSet<T> : DynamicObject
  102. {
  103. /// <summary></summary>
  104. public override IEnumerable<string> GetDynamicMemberNames()
  105. {
  106. return new List<string>(_origin.Keys).ToArray();
  107. }
  108. /// <summary></summary>
  109. public override bool TryGetMember(GetMemberBinder binder, out object result)
  110. {
  111. var contains = false;
  112. result = Get(binder.Name, ref contains);
  113. if (_always) return true;
  114. return contains;
  115. }
  116. /// <summary></summary>
  117. public override bool TrySetMember(SetMemberBinder binder, object value)
  118. {
  119. var setted = Set(binder.Name, (T)value);
  120. if (_always) return true;
  121. return setted;
  122. }
  123. internal static ExpandoObject Expando(ObjectSet<T> os)
  124. {
  125. if (os == null) return null;
  126. var eo = new ExpandoObject();
  127. var dict = eo as IDictionary<string, object>;
  128. foreach (var kvp in os._origin) dict.Add(kvp.Key, kvp.Value);
  129. return eo;
  130. }
  131. internal static ExpandoObject[] Expando(ObjectSet<T>[] oss)
  132. {
  133. if (oss == null) return null;
  134. var eos = new ExpandoObject[oss.Length];
  135. for (var i = 0; i < oss.Length; i++) eos[i] = Expando(oss[i]);
  136. return eos;
  137. }
  138. }
  139. #endif
  140. }