C#动态对象 dynamic
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text.RegularExpressions; 5 using System.Dynamic; 6 using System.Reflection; 7 8 namespace DHUI.Base.Util 9 { 10 /// <summary> 11 /// 扩展动态对象 12 /// </summary> 13 public class DynamicObjectEx 14 : DynamicObject 15 { 16 #region 成员 17 18 private Dictionary<string, object> _dc; 19 20 #endregion 21 22 #region 构造 23 24 /// <summary> 25 /// 构造动态对象 26 /// </summary> 27 public DynamicObjectEx() 28 { 29 _dc = new Dictionary<string, object>(); 30 } 31 /// <summary> 32 /// 构造动态对象 33 /// </summary> 34 /// <param name="kv">字典</param> 35 public DynamicObjectEx(Dictionary<string, object> kv) 36 { 37 _dc = kv; 38 } 39 40 #endregion 41 42 #region 属性 43 44 /// <summary> 45 /// 键值对 46 /// </summary> 47 public Dictionary<string, object> KeyValues 48 { 49 get 50 { 51 return _dc; 52 } 53 } 54 55 #endregion 56 57 #region 方法 58 59 /// <summary> 60 /// 移除属性或索引 61 /// </summary> 62 /// <param name="nameOrIndexes">属性名或索引列表</param> 63 /// <returns></returns> 64 public void Remove(params object[] nameOrIndexes) 65 { 66 if (nameOrIndexes.Length > 0) 67 { 68 string propertyName = string.Join(",", nameOrIndexes); 69 70 //非静态属性 71 if (null == this.GetType().GetProperty(propertyName)) 72 { 73 //动态属性 74 lock (this) 75 { 76 if (_dc.ContainsKey(propertyName)) 77 { 78 _dc.Remove(propertyName); 79 } 80 } 81 } 82 } 83 } 84 /// <summary> 85 /// 清除动态属性 86 /// </summary> 87 public void Clear() 88 { 89 lock (this) 90 { 91 _dc.Clear(); 92 } 93 } 94 /// <summary> 95 /// 是否存在属性或索引 96 /// </summary> 97 /// <param name="nameOrIndexes">属性名或索引列表</param> 98 /// <returns></returns> 99 public bool Exists(params object[] nameOrIndexes) 100 { 101 if (nameOrIndexes.Length > 0) 102 { 103 string propertyName = string.Join(",", nameOrIndexes); 104 105 //静态属性 106 if (null != this.GetType().GetProperty(propertyName)) 107 { 108 return true; 109 } 110 //动态属性 111 lock (this) 112 { 113 return _dc.ContainsKey(propertyName); 114 } 115 } 116 117 return false; 118 } 119 /// <summary> 120 /// 取属性或索引值 121 /// </summary> 122 /// <param name="defaultValue">默认值</param> 123 /// <param name="nameOrIndexes">属性名或索引列表</param> 124 /// <returns></returns> 125 public object GetValue(object defaultValue, params object[] nameOrIndexes) 126 { 127 if (nameOrIndexes.Length > 0) 128 { 129 string propertyName = string.Join(",", nameOrIndexes); 130 131 //静态属性 132 PropertyInfo pi = this.GetType().GetProperty(propertyName); 133 if (null != pi) 134 { 135 return pi.GetValue(this, null); 136 } 137 //动态属性 138 lock (this) 139 { 140 if (_dc.ContainsKey(propertyName)) 141 return _dc[propertyName]; 142 else 143 { 144 _dc.Add(propertyName, defaultValue); 145 } 146 } 147 } 148 149 return defaultValue; 150 } 151 /// <summary> 152 /// 设置域值 153 /// </summary> 154 /// <param name="value">设置值</param> 155 /// <param name="nameOrIndexes">属性名或索引列表</param> 156 public void SetValue(object value, params object[] nameOrIndexes) 157 { 158 if (nameOrIndexes.Length > 0) 159 { 160 string propertyName = string.Join(",", nameOrIndexes); 161 162 PropertyInfo pi = this.GetType().GetProperty(propertyName); 163 if (null == pi) 164 { 165 //动态属性 166 lock (this) 167 { 168 if (_dc.ContainsKey(propertyName)) 169 _dc[propertyName] = value; 170 else 171 { 172 _dc.Add(propertyName, value); 173 } 174 } 175 } 176 else 177 { 178 //静态属性 179 pi.SetValue(this, value, null); 180 } 181 } 182 } 183 /// <summary> 184 /// 取动态索引值对 185 /// </summary> 186 /// <param name="indexes">索引列表</param> 187 /// <returns></returns> 188 public Dictionary<object[], object> GetIndex2Value(params object[] indexes) 189 { 190 Dictionary<object[], object> i2v = new Dictionary<object[], object>(); 191 if (indexes.Length > 0) 192 { 193 string propertyName = string.Join(",", indexes); 194 lock (this) 195 { 196 var keys = _dc.Keys.Where(k => Regex.IsMatch(k, string.Format("^{0}(,[^,]+)*$", Regex.Escape(propertyName)))).OrderBy(k => k).Select(k => new IndexComparer(k, indexes.Length)); 197 foreach (IndexComparer k in keys) 198 { 199 i2v.Add(k.Key.Split(','), _dc[k.Key]); 200 } 201 } 202 } 203 204 return i2v; 205 } 206 /// <summary> 207 /// 取顶层动态索引值对 208 /// </summary> 209 /// <returns></returns> 210 public Dictionary<string, object> GetRootIndex2Value() 211 { 212 Dictionary<string, object> i2v = new Dictionary<string, object>(); 213 lock (this) 214 { 215 foreach (string k in _dc.Keys) 216 if (k.IndexOf(',') < 0) 217 i2v.Add(k, _dc[k]); 218 } 219 220 return i2v; 221 } 222 /// <summary> 223 /// 取索引属性 224 /// </summary> 225 /// <param name="binder">绑定器</param> 226 /// <param name="indexes">索引列表</param> 227 /// <param name="result">获取值</param> 228 /// <returns></returns> 229 public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) 230 { 231 result = null; 232 233 string propertyName = string.Join(",", indexes); 234 lock (this) 235 { 236 if (_dc.ContainsKey(propertyName)) 237 result = _dc[propertyName]; 238 } 239 240 return true; 241 } 242 /// <summary> 243 /// 设置索引属性 244 /// </summary> 245 /// <param name="binder">绑定器</param> 246 /// <param name="indexes">索引列表</param> 247 /// <param name="value">设定值</param> 248 /// <returns></returns> 249 public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) 250 { 251 string propertyName = string.Join(",", indexes); 252 lock (this) 253 { 254 if (_dc.ContainsKey(propertyName)) 255 _dc.Remove(propertyName); 256 257 _dc.Add(propertyName, value); 258 } 259 return true; 260 } 261 /// <summary> 262 /// 取动态属性 263 /// </summary> 264 /// <param name="binder">绑定器</param> 265 /// <param name="result">结果值</param> 266 /// <returns></returns> 267 public override bool TryGetMember(GetMemberBinder binder, out object result) 268 { 269 result = null; 270 271 lock (this) 272 { 273 if (_dc.ContainsKey(binder.Name)) 274 result = _dc[binder.Name]; 275 } 276 277 return true; 278 } 279 /// <summary> 280 /// 设置动态属性 281 /// </summary> 282 /// <param name="binder">绑定器</param> 283 /// <param name="value">设置值</param> 284 /// <returns></returns> 285 public override bool TrySetMember(SetMemberBinder binder, object value) 286 { 287 lock (this) 288 { 289 if (_dc.ContainsKey(binder.Name)) 290 _dc.Remove(binder.Name); 291 292 _dc.Add(binder.Name, value); 293 } 294 return true; 295 } 296 297 #endregion 298 299 /// <summary> 300 /// 索引比较器 301 /// </summary> 302 private class IndexComparer 303 : IComparable 304 { 305 306 #region 构造 307 308 public IndexComparer(string key, int startPos) 309 { 310 _key = key; 311 _startPos = startPos; 312 } 313 314 #endregion 315 316 #region 成员 317 318 private int _startPos; 319 private string _key; 320 321 #endregion 322 323 #region 属性 324 325 /// <summary> 326 /// 键值 327 /// </summary> 328 public string Key 329 { 330 get 331 { 332 return _key; 333 } 334 } 335 336 #endregion 337 338 #region IComparable 成员 339 340 public int CompareTo(object obj) 341 { 342 try 343 { 344 string[] a = _key.Split(','); 345 string[] b = (obj as IndexComparer)._key.Split(','); 346 int m = a.Length; 347 if (m > b.Length) m = b.Length; 348 int c; 349 for (int i = _startPos; i < m; i++) 350 { 351 decimal a1, b1; 352 if (decimal.TryParse(a[i], out a1) && decimal.TryParse(b[i], out b1)) 353 { 354 if (a1 < b1) 355 return -1; 356 else if (a1 > b1) 357 return 1; 358 } 359 else 360 { 361 c = string.Compare(a[i], b[i]); 362 if (0 != c) 363 return c; 364 } 365 } 366 if (a.Length < b.Length) 367 return -1; 368 else 369 return 1; 370 } 371 catch 372 { 373 374 } 375 376 return -1; 377 } 378 379 #endregion 380 } 381 } 382 }
dynamic 的相关文章
浙公网安备 33010602011771号