C# 4.0 新增的动态性(http://www.iteye.com/news/4002)

C# 4.0又开始添加新的技术特点,这次它的老师是来自动态语言python与ruby。MS fans们以极大的热情和开放的心态,投入这场静态语言与动态语言的融合中去。

除了进一步完善了DLR这个为动态语言而设计的runtime(这一完美设计基本就宣判了 ruby.net的死刑,奠定了ironruby的胜局),C# 4.0也为此打开了门户,在C# 4.0中,添加dynamic这一关键字,这个关键字告诉编译器:“别担心我要做什么,运行时的时候就明了”。请看例子

Java代码 复制代码
  1. using System;
  2. using Microsoft.CSharp.RuntimeBinder;
  3. using System.Scripting.Actions;
  4. using System.Linq.Expressions;
  5. namespace ConsoleApplication1
  6. {
  7. publicclass Program
  8. {
  9. staticvoid Main(string[] args)
  10. {
  11. DoSomethingDynamic(7);
  12. DoSomethingDynamic(new Actor());
  13. DoSomethingDynamic(new DynamicThing());
  14. Console.ReadLine();
  15. }
  16. staticvoid DoSomethingDynamic(dynamic thing)
  17. {
  18. try
  19. {
  20. thing.Act();
  21. }
  22. catch (RuntimeBinderException)
  23. {
  24. Console.WriteLine("thing does not implement Act");
  25. }
  26. }
  27. }
  28. publicclass Actor
  29. {
  30. publicvoid Act()
  31. {
  32. Console.WriteLine("Actor.Act() was called");
  33. }
  34. }
  35. publicclass DynamicThing : IDynamicObject
  36. {
  37. public MetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
  38. {
  39. returnnew CustomMetaObject(parameter);
  40. }
  41. }
  42. publicclass CustomMetaObject : MetaObject
  43. {
  44. public CustomMetaObject(Expression parameter) : base(parameter, Restrictions.Empty){ }
  45. public override MetaObject Call(CallAction action, MetaObject[] args)
  46. {
  47. Console.WriteLine("A method named: '{0}' was called", action.Name);
  48. returnthis;
  49. }
  50. }
  51. }
using System;
using Microsoft.CSharp.RuntimeBinder;
using System.Scripting.Actions;
using System.Linq.Expressions;
namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            DoSomethingDynamic(7);
            DoSomethingDynamic(new Actor());
            DoSomethingDynamic(new DynamicThing());
            Console.ReadLine();
        }
        static void DoSomethingDynamic(dynamic thing)
        {
            try
            {
                thing.Act();
            }
            catch (RuntimeBinderException)
            {
                Console.WriteLine("thing does not implement Act");
            }
        }
    }
    public class Actor
    {
        public void Act()
        {
            Console.WriteLine("Actor.Act() was called");
        }
    }
    public class DynamicThing : IDynamicObject
    {
        public MetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
        {
            return new CustomMetaObject(parameter);
        }
    }
    public class CustomMetaObject : MetaObject
    {
        public CustomMetaObject(Expression parameter) : base(parameter, Restrictions.Empty){ }
        public override MetaObject Call(CallAction action, MetaObject[] args)
        {
            Console.WriteLine("A method named: '{0}' was called", action.Name);
            return this;
        }
    }
}



例子中的方法DoSomethingDynamic(dynamic thing),拥有一个带有dynamic关键字的变量thing。我们调用thing的方法Act(); 编译器无法检查thing是不是有Act方法直到运行的时候,为保险起见,我们用个try-catch块来捕捉异常。当然另一方面,鸭子类型(duck type)使得编程时无法使用智能提示,你可以在变量后面随手涂鸦,thing.Foo(), thing + 56, thing.X = "hello", var y = thing[12],这堆东西都能被编译。

接下来,我们在Main入口里反复调用了DoSomethingDynamic,传送了不同类型的参数:
首先是整数类型7。Int32没有Act方法,所以RuntimeBinderException被抛出。
其实是一个正常的类Actor带有一个Act方法,因此一切正常。
最后是继承了IDynamicObject的类DynamicThing ,IDynamicObject只有一个GetMetaObject方法需要被实现. GetMetaObject返回一个MetaObject,而你要做的实现一个如何处理方法调用的CustomMetaObject.我们的 CustomMetaObject重载了Call方法,并简单打印出方法的名字.

C# 现在主要还是静态类型语言,而Anders确定静态类型对于大型可伸缩系统是更好的范例。同时他也觉察到了动态特性的魅力,并为C#添加了诸如VB和其他动态语言的特性。

posted @ 2012-06-12 16:11  楼上少年  阅读(248)  评论(0编辑  收藏  举报