背景: 在Coding中有時候會遇到一些需要解析的數據,可是數據的字段數量和名稱未統一,我們沒法定義實體類來對應。那么我們就會想到通過C#的dynamic動態類來實現,如果大家注意的話一些ORM框架里面貌似都有用到dynamic來實現一部分功能。
一.Dynamic的基本應用
1.1 通過.PRopertyName來添加屬性,和javaScript的對象差不多.不過對于我們所要解析的數據,我們事先也許根本不知道屬性名稱,所以用這種方法意義不大.
dynamic myObj = new ExpandoObject();myObj.Name = "Frank";Console.WriteLine(myObj.Name);
二.Dynamic自定義屬性名稱.
2.1: 繼承DynamicObject,里面提供了各種方法,重寫后可以實現屬性的添加.
public sealed class MyExtendsObject : DynamicObject { private readonly Dictionary<string, object> _properties; public MyExtendsObject(Dictionary<string, object> properties) { _properties = properties; } public override IEnumerable<string> GetDynamicMemberNames() { return _properties.Keys; } public override bool TryGetMember(GetMemberBinder binder, out object result) { if (_properties.ContainsKey(binder.Name)) { result = _properties[binder.Name]; return true; } else { result = null; return false; } } public override bool TrySetMember(SetMemberBinder binder, object value) { if (_properties.ContainsKey(binder.Name)) { _properties[binder.Name] = value; return true; } else { return false; } } }
2.2 通過字典來添加屬性和賦值
public static void Main(string[] args) { dynamic myObj = new ExpandoObject(); Dictionary<string, object> dic = new Dictionary<string, object>() { {"Name","Frank"}, {"Age",23} }; myObj = new MyExtendsObject(dic); Console.WriteLine(myObj.Age); //23 }
三.Dynamic解析xml.
3.1 定義xml文件:
<?xml version="1.0" encoding="utf-8" ?><Person> <Name>Frank</Name> <Age>23</Age> <Address>TianFu SoftWarePark</Address></Person>
3.2 繼承DynamicObject
 public sealed class MyExtensXMLObj : DynamicObject    {        private readonly XElement node;        public MyExtensXMLObj(XElement node)        {            this.node = node;        }        public override bool TrySetMember(SetMemberBinder binder, object value)        {            var elements = node.Elements().ToList();            var currentElement = elements.FirstOrDefault(x => x.Name == binder.Name);            if (currentElement != null)            {                currentElement.Value = value as string;                return true;            }            else            {                return false;            }        }        public override bool TryGetMember(GetMemberBinder binder, out object result)        {            var elements = node.Elements().ToList();            var currentElement = elements.FirstOrDefault(x => x.Name == binder.Name);            if (currentElement != null)            {                result = currentElement.Value;                return true;            }            else            {                result = null;                return false;            }        }    }3.3 結果輸出:
public static void Main(string[] args) { XElement root = XElement.Load(@"Test.xml"); dynamic personList = new MyExtensXMLObj(root); Console.WriteLine(personList.Name); // Frank }
四. 繼承規則.
1. 子類里面包含一個私有變量,用于存儲數據. 這暫且叫做Data;
2.TryGetMember(GetMemberBinder binder, out object result) 方法實現對數據的獲取. binder.Name就是需要獲取的屬性的名稱,result 是獲取的屬性值. 通過binder.Name在Data中獲取到對應的屬性值,傳出到外面.(注意到了吧result是out參數)
3.TrySetMember(SetMemberBinder binder, object value) 對存在的屬性進行賦值. 上面的Set方法中,我都判斷了binder.Name在data里面是否存在。如果不存在就無法賦值。返回false,如果外面對不存在的屬性復制那么將會報錯.
 
  | 
新聞熱點
疑難解答