public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
if (binder.Name == "Value")
{
result = null;
if (binder.Name == "Value")
result = _elements[0].Value;
else if (binder.Name == "Count")
result = _elements.Count;
else
{
var attr = _elements[0].Attribute(
XName.Get(binder.Name));
if (attr != null)
result = attr;
else
{
var items = _elements.Descendants(
XName.Get(binder.Name));
if (items == null ||items.Count() == 0) return false;
result = new DynamicXml(items);
}
}
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
int ndx = (int)indexes[0]; result = new DynamicXml(_elements[ndx]);
return true;
}
public IEnumerator GetEnumerator()
{
foreach (var element in _elements)
yield return new DynamicXml(element);
}
}
else if (binder.Name == "Count")
result = _elements.Count;
else
{
var attr = _elements[0].Attribute(
XName.Get(binder.Name));
if (attr != null)
result = attr;
else
{
var items = _elements.Descendants(
XName.Get(binder.Name));
if (items == null ||items.Count() == 0) return false;
result = new DynamicXml(items);
}
}
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
int ndx = (int)indexes[0]; result = new DynamicXml(_elements[ndx]);
return true;
}
public IEnumerator GetEnumerator()
{
foreach (var element in _elements)
yield return new DynamicXml(element);
}
}
运用
在具体运用中, 有些地方是非常有趣的, 因为我们有了dynamic, 所以你可以用同一个变量去获取不同结构的XML文件. 运用代码如下:
static void Main(string[] args)
{
string xml = @"<root>
<books>
<book>
<author>John Savacki</author>
<title>E.G.Title</title>
<price>20.50</price>
</book>
<book>
<author>Tom Curly</author>
<title>E.G.Title 2</title>
<price>26.50</price>
</book>
</books>
</root>"; dynamic dx = new DynamicXml(xml);
Console.WriteLine("----- Book List -----");
foreach (dynamic b in dx.books.book)
{
Console.WriteLine("author='{0}'", b.author.Value);
print(b);
}
Console.WriteLine("------ Book List End ------");
string xml2 = @"<root>
<products>
<product>
<title>iPhone 4</title>
<price>2222.50</price>
<quantity>10</quantity>
</product>
<product>
<title>Lenovo IdeaPad</title>
<price>5432.50</price>
<quantity>15</quantity>
</product>
</products>
</root>";
dx = new DynamicXml(xml2);
Console.WriteLine("----- Product List -----");
foreach (dynamic b in dx.products.product)
{
Console.WriteLine("quantity='{0}'", b.quantity.Value);
print(b);
}
Console.WriteLine("------ Product List End ------");
Console.Read();
}
{
string xml = @"<root>
<books>
<book>
<author>John Savacki</author>
<title>E.G.Title</title>
<price>20.50</price>
</book>
<book>
<author>Tom Curly</author>
<title>E.G.Title 2</title>
<price>26.50</price>
</book>
</books>
</root>"; dynamic dx = new DynamicXml(xml);
Console.WriteLine("----- Book List -----");
foreach (dynamic b in dx.books.book)
{
Console.WriteLine("author='{0}'", b.author.Value);
print(b);
}
Console.WriteLine("------ Book List End ------");
string xml2 = @"<root>
<products>
<product>
<title>iPhone 4</title>
<price>2222.50</price>
<quantity>10</quantity>
</product>
<product>
<title>Lenovo IdeaPad</title>
<price>5432.50</price>
<quantity>15</quantity>
</product>
</products>
</root>";
dx = new DynamicXml(xml2);
Console.WriteLine("----- Product List -----");
foreach (dynamic b in dx.products.product)
{
Console.WriteLine("quantity='{0}'", b.quantity.Value);
print(b);
}
Console.WriteLine("------ Product List End ------");
Console.Read();
}
我把print函数专门拿出来, 故弄玄虚一下, 因为两个XML的结构有类似的地方, 所以可以同时使用下面的函数. -- 当然对于这样的情况,我们也可以为此定义一个interface.
static void print(dynamic b)
{
Console.WriteLine("Title='{0}'", b.title.Value);
Console.WriteLine("price='{0}'", b.price.Value);
}
不是什么很深奥的东西, 但是希望可以为有同样问题的朋友们节省一些时间.
如果可以较好的掌握Dynamic, 可以节省一些反射方面的代码