DotNet 4 学习笔记之 2-------------Dynamic 初步

接着上回.

Dynamic也是Dotnet 4.0的一个重要的feature.

通常的动态语言,如JavaScript, Python, Ruby 都能做到动态.即其类型在编译时能不检查,而等到运行时方知.

当然,动态化通常受到了IDE,效率等影响.

.net 4.0引入 Dynamic Language Runtime (DLR),为其带来了动态语言的一些feature.

下面我们进行简单的研究.

类型动态 

            dynamic str = "string";
            Console.WriteLine(str.GetType().ToString());

 

 以上例子非常简单,输出了一个动态对象其真实的类型.其输出是System.String

或许你会认为其和var关键字起的效果是一样的.其实不然.

最明显的,你会发现,dynamic做了IDE屏蔽,其作为动态类型在编译时,是不推测其类型的. 

就以上文例子,其 GetType()方法在IDE(Vs2010)里被解释成了dynamic expression,其只有到了运行时方能被resolve

相反,var关键字是一个典型的语法糖,其在编译时已经被正确解析成自己真实的类型.

关于这点,有兴趣的朋友可以通过Reflector看看.

 

因为这个特点,我们反射时就不必再像以前那样了。

//以前的方法
Type type=...;
type.GetMethod(
"method name",...).Invoke(data,...);
//现在的方法
dynamic obj=Activator.CreateInstance(...);
obj.XXmethod()

 

Dynamic的几个实现

.net 4.0提供了几个dynamic类型或接口,如DynamicObject,ExpandoObject,IDynamicMetaObjectProvider

其都是在System.Dynamic命名空间下。

 ExpandoObject

 ExpandoObject提供了一个具有可扩充的动态对象。这里的可扩充,包括对其不同节点上的属性或是方法的扩充。

最简单的例子,通过这个对象,我们便可以实现类似json里的某些功能。

 //JS code

var test={
   name:
"test",
   func:
function(){
       alert();
   }
};

 

类似的Csharp代码如下

dynamic test = new ExpandoObject();
test.Name 
= "test";
test.Func 
= new Action(() => Console.WriteLine("alert "+test.Name));
Console.WriteLine(test.Name);
test.Func();

通过以上特点,我们在处理多节点对象(如XML)就非常方便了。

 

DynamicObject 

通常我们自定一个类去继承 DynamicObject,而当我们对某个dynamic 对象使用XX方法或属性时,其TryGetMember方法都能被拦截到。

所访问的方法或属性名是在 public virtual bool TryGetMember(GetMemberBinder binder, out object result);的GetMemberBinder.Name中得以体现。

举个例子吧

代码
    class Program
    {
        
static void Main(string[] args)
        {
            dynamic test 
= new TestDynamicObject();
            Console.WriteLine(test.Test);
            Console.ReadKey();
        }
    }

    
class TestDynamicObject : DynamicObject
    {
        
public TestDynamicObject( )
        {
           
        }
        
public override bool TryGetMember(GetMemberBinder binder,out object result)
        {
            
string nodeName = binder.Name;
            Console.WriteLine(binder.Name
+" run");
            result 
= DateTime.Now;
            
return true;
        }
    }

 

 以上代码输出类似如下:

Test run

2010-02-25 15:15:42


总结 

当然,DLR并非如上介绍的这么简单,其也支持了某些动态语言的binder,如IronPython等。在PDC09中,就有相关的video。 

本文也只是简单了介绍了DLR的一些皮毛罢了。 

 To Be Continue....

posted @ 2010-02-25 15:31  Edwin Tai  阅读(2141)  评论(6编辑  收藏  举报