歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C#筆記---動態類(Dynamic)應用

C#筆記---動態類(Dynamic)應用

日期:2017/3/1 9:28:44   编辑:Linux編程

背景: 在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,如果外面對不存在的屬性復制那麼將會報錯.

Copyright © Linux教程網 All Rights Reserved