接着上回.

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....

 

Comments

ffxiv gil

Usually we set a class to inherit from DynamicObject, and when we use a dynamic object method or property XX, the TryGetMember methods can be intercepted.The access method or property name is in public virtual bool TryGetMember (GetMemberBinder binder, out object result); the GetMemberBinder.Name is embodied.Yeah,i think so.

Zula Vanta

Hands down, Apple's app store wins by a mile. It's a huge selection of all sorts of apps vs a rather sad selection of a handful for Zune. Microsoft has plans, especially in the realm of games, but I'm not sure I'd want to bet on the future if this aspect is important to you. The iPod is a much better choice in that case.