度娘許久,找不到我滿意的答案,於是自己東湊西湊實現一個。 DynamicObject擴展--實現JSON和DynamicObject的序列化與反序列化,親測良好。 看代碼 ...
度娘許久,找不到我滿意的答案,於是自己東湊西湊實現一個。
DynamicObject擴展--實現JSON和DynamicObject的序列化與反序列化,親測良好。
看代碼
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.Runtime.CompilerServices; using Newtonsoft.Json; namespace ConsoleApplication { [Serializable] public class ExtensionDynamicObject : DynamicObject, IDictionary<string, object>, ICloneable, INotifyPropertyChanged { private readonly IDictionary<string, object> _values = new Dictionary<string, object>(); #region IDictionary<String, Object> 介面實現 public object this[string key] { get { return _values[key]; } set { _values[key] = value; OnPropertyChanged(key); } } public int Count { get { return _values.Count; } } public bool IsReadOnly { get { return _values.IsReadOnly; } } public ICollection<string> Keys { get { return _values.Keys; } } public ICollection<object> Values { get { return _values.Values; } } public void Add(KeyValuePair<string, object> item) { _values.Add(item); } public void Add(string key, object value) { _values.Add(key, value); } public void Clear() { _values.Clear(); } public bool Contains(KeyValuePair<string, object> item) { return _values.Contains(item); } public bool ContainsKey(string key) { return _values.ContainsKey(key); } public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) { _values.CopyTo(array, arrayIndex); } public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { return _values.GetEnumerator(); } public bool Remove(KeyValuePair<string, object> item) { return _values.Remove(item); } public bool Remove(string key) { return _values.Remove(key); } public bool TryGetValue(string key, out object value) { return _values.TryGetValue(key, out value); } IEnumerator IEnumerable.GetEnumerator() { return _values.GetEnumerator(); } #endregion #region ICloneable 介面實現 public object Clone() { var clone = new ExtensionDynamicObject() as IDictionary<string, object>; foreach (var key in _values.Keys) { clone[key] = _values[key] is ICloneable ? ((ICloneable)_values[key]).Clone() : _values[key]; } return clone; } #endregion #region INotifyPropertyChanged 介面實現 public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion /// <summary> /// 獲取屬性值 /// </summary> /// <param name="propertyName"></param> /// <returns></returns> public object GetPropertyValue(string propertyName) { if (_values.ContainsKey(propertyName) == true) { return _values[propertyName]; } return null; } /// <summary> /// 設置屬性值 /// </summary> /// <param name="propertyName"></param> /// <param name="value"></param> public void SetPropertyValue(string propertyName, object value) { if (_values.ContainsKey(propertyName) == true) { _values[propertyName] = value; } else { _values.Add(propertyName, value); } } /// <summary> /// 實現動態對象屬性成員訪問的方法,得到返回指定屬性的值 /// </summary> /// <param name="binder"></param> /// <param name="result"></param> /// <returns></returns> public override bool TryGetMember(GetMemberBinder binder, out object result) { result = GetPropertyValue(binder.Name); return result != null; } /// <summary> /// 實現動態對象屬性值設置的方法。 /// </summary> /// <param name="binder"></param> /// <param name="value"></param> /// <returns></returns> public override bool TrySetMember(SetMemberBinder binder, object value) { SetPropertyValue(binder.Name, value); return true; } ///// <summary> /// http://blog.csdn.net/hawksoft/article/details/7534332 ///// 動態對象動態方法調用時執行的實際代碼 ///// </summary> ///// <param name="binder"></param> ///// <param name="args"></param> ///// <param name="result"></param> ///// <returns></returns> //public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) //{ // var theDelegateObj = GetPropertyValue(binder.Name) as DelegateObj; // if (theDelegateObj == null || theDelegateObj.CallMethod == null) // { // result = null; // return false; // } // result = theDelegateObj.CallMethod(this, args); // return true; //} public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { return base.TryInvoke(binder, args, out result); } } public class ExcelModelDynamicObject : ExtensionDynamicObject { public string Name { get { return this["Name"].ToString(); } set { this["Name"] = value; } } public string Age { get { return this["Age"].ToString(); } set { this["Age"] = value; } } } class Program { static void Main(string[] args) { dynamic eo = new ExcelModelDynamicObject(); eo.Age = 25; eo.Name = "Allen"; eo["Title"] = "Test Dynamic Object"; eo.Content = "Hi,Allen."; string jsonString = JsonConvert.SerializeObject(eo); //{"Age":25,"Name":"Allen","Title":"Test Dynamic Object","Content":"Hi,Allen."} dynamic eo2 = JsonConvert.DeserializeObject<ExcelModelDynamicObject>(jsonString); string value1 = eo2.Title;//Hello string value2 = eo2.Content;//Hi,Allen. ExcelModelDynamicObject eo3 = eo2; string value3 = eo3.Age; string value4 = eo3.Name; //very done. } } }