C#动静结合编程之三:Duck Typing
2009-03-26 08:20:24 来源:WEB开发网上面的例子中,虽然person对象没有实现IPerson接口,我们一样可以通过Duck.Create<IPerson>(person)创建鸭子对象调用person的属性和方法。这种把接口和对象粘合的方式与委托和方法的粘合方式非常接近,真正达到了我们所谓把委托思想应用于对象的想法。
C#中要实现Duck.Create<T>的功能,可以通过Emit动态创建实现T接口的代理类,在代理类中拦截方法调用,并将方法调用转换成target对象上的反射调用。Castle开源项目的DynamicProxy是一个很好用的工具,在它的帮助下很容易实现代理类的创建和方法调用的拦截。
动态类型
事实上,duck typing是动态类型概念的一种。C#4.0已经通过dynamic关键字来实现动态类型,让我们先来看看下面的示例:
string json = @"{ ""FirstName"": ""John"", ""LastName"": ""Smith"", ""Age"": 21 }";
dynamic person = CreateFromJson(json);
Console.WriteLine("{0} will be {1} next year", person.FirstName, person.Age + 1);
Console.WriteLine(person.ToJson());
person.Play("basketball");//不存在的方法,可以通过编译,但会抛出运行时异常
通过dynamic关键字,我们不需要在编译时为person对象指定类型,编译器不会进行类型检查,而是将对象的属性访问和方法调用转换为反射调用,所以,只要对象的运行时类型能通过反射找到匹配的属性或方法即可。
上面的例子通过json创建了一个dynamic对象,就像javascript中操作json一样方便。在运行 时,person.FirstName和person.Age能通过反射正确地进行属性访问,person.ToJson()也可以正确地执行,但 person.Play( "basketball")由于运行时类型不存在该方法而抛出异常。
更多精彩
赞助商链接