C#4.0入门 第一章 dynamic类型—第一页 dynamic类型((转)


dynamic类型


C#从1.0版开始,就可以即使不知道一个对象的类型,在编译时也可以动态访问这个对象的信息。只要使用反射就可以了。


使用反射访问对象的成员信息




 
class A
{
public readonly string MyName = "陆凌牛";
public static object GetObjectA() { return new A(); }
}
class Program
{
static void Main(string[] args)
{
object a = A.GetObjectA();
var name = a.GetType().GetField("MyName").GetValue(a);
Console.WriteLine(name);
}
}


上例的执行结果




 陆凌牛



诚如您所见,Main方法中并不知道在GetObjectA方法中返回了什么类型的对象,利用反射功能,可以得到返回对象的字段的值。也就是说,这就是所谓的“动态”处理。


在C#4.0中导入了dynamic类型,可以大幅度简化这种操作。


使用dynamic类型访问对象的成员信息




 
using System;
class A
{
public readonly string MyName = "陆凌牛";
public static dynamic GetObjectA() { return new A(); }
}

class Program
{
static void Main(string[] args)
{
dynamic a = A.GetObjectA();
Console.WriteLine(a.MyName);
}
}



当然,在Main中仍然不知道GetObjectA方法返回的对象为A类型,但仍然可以得到MyName这个字段的值。这是因为,只要名字保持一致,就可以进行访问了,与反射中的访问功能是相同的。


也就是说,因为名字是否一致不是在编译时检查的,而是在运行时检查的。即使不一致,也不是编译时错误,而是运行时抛出异常。同时,运行时因为要寻找与给定名字相同的成员,运行速度会有相应的延迟。

■ 统一调用

dynamic类型的特征之一为,虽然不知道对象的类型也可以对对象进行访问,但在某种情况下即使知道了对象的类型,也必须通过dynamic类型进行访问。



下例为两种“鸟”类的定义,这两个类没有继承关系,完全是独立存在的。这种情况下,用普通的方法不能统一调用它们中的某个方法。即使可以另外进行封装,但始终还是要分别针对不同的类分开调用。因为象这样两个没有继承关系的类,要统一调用它们中某个函数是不可能的。但是,现在通过dynamic类型,只要名字,参数与类型保持一致,就可以统一调用了。下例中在统一鸣叫方法中,集中调用了两个类中的同一个方法。


通过dynamic类型进行访问




 
using System;
class 黑鸟
{
public void 鸣叫()
{
Console.WriteLine("我是黑鸟!");
}
}

class 白鸟
{
public void 鸣叫()
{
Console.WriteLine("我是白鸟");
}
}

class Program
{
private static void 统一鸣叫(dynamic 鸟)
{
鸟.鸣叫();
}

static void Main(string[] args)
{
统一鸣叫((dynamic)new 黑鸟());
统一鸣叫((dynamic)new 白鸟());
}
}


上例的执行结果




 我是黑鸟!
我是白鸟!
posted @ 2011-06-11 15:53  董雨  阅读(247)  评论(0编辑  收藏  举报