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

dynamic 的相关文章

C#动态对象(dynamic)示例(实现方法和属性的动态)

C#4.0的动态性大大增强——dynamic

posted on 2014-11-25 16:40  二狗你变了  阅读(594)  评论(0)    收藏  举报

导航