转贴一段C#代码 @ 10/26/2009

学习类
from: https://gist.github.com/5ab9961fc8b2454a4531
作者: Jeffrey Zhao

使用静态地动态类型(statically dynamic typing),二十行代码在C#中搞定Ruby Markup Builder的基本功能(当然不够完整)
// XmlMarkupBuilder.cs
public class XmlMarkupBuilder : DynamicObject {
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
        XElement xml = new XElement(binder.Name);

        var attrCount = binder.CallInfo.ArgumentNames.Count;
        var elementCount = args.Length - attrCount;

        for (int i = 0; i < elementCount; i++) {
            xml.Add(args[i]);
        }

        for (var i = 0; i < attrCount; i++) {
            var attrName = binder.CallInfo.ArgumentNames[i];
            if (attrName[0] == '@') attrName = attrName.Substring(1);

            xml.Add(new XAttribute(attrName, args[i + elementCount]));
        }

        result = xml;
        return true;
    }
}

class Program {
    static void Main(string[] args) {
        dynamic b = new XmlMarkupBuilder();
        XElement xml =
            b.Persons(
                b.Person("Tom", age: 10),
                b.Person("Jerry", age: 8));

        Console.WriteLine(xml);
        // output:
        // <Persons>
        // <Person age="10">Tom</Person>
        // <Person age="8">Jerry</Person>
        // </Persons>
    }
}

从dynamic关键字上可以看出,这是C# 4.0中新增的功能。
DynamicObject是个特殊的对象,简单地说它的行为可以被“扩展”——是如动态语言般真正的扩展,而非静态的多态。当我们使用dynamic修饰变量后,在它之上的方法调用会由编译器和DLR配合出不一样的行为。例如,我们在调用一个方法的时候,DLR会先检查这个动态对象上是否存在符合这个签名的方法,存在则最好,否则便会调用TryInvokeMember来“执行”一个动态方法,而它的参数便是此次调用的全部信息。这样的做法被称为“Method Missing”操作,事实上Ruby Markup Builder也是使用Ruby对象中的这个特性来实现“调用什么方法,便生成什么元素”的功能。
事实上,我们还可以这么用:
var persons = new [] { new Person("Tom", 10), new Person("Jerry", 8) };
XElement xml2 =
    b.persons(
        from p in persons
        select b.person(p.Name, age: p.Age));

XmlMarkupBuilder对LINQ的直接支持得益于XElement无与伦比的“包容性”(LINQ to XML是C# 3.5的新特性)。而age: 10这样的代码使用了命名参数(Named Parameters)(C# 4.0的新特性)。
发布于 10/26/2009 18:42:03 | 评论:0

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1170
  • 评论数:2013