C#4.0和VS2010新特性

来源:互联网 发布:聂子佩 知乎 编辑:程序博客网 时间:2024/05/16 19:23

dynamic初探: 

            以前因为某些特殊原因,需要动态的调用外部类(假设这个类是实现了某个带有参数的接口函数的),通常我们只能用反射了。示例代码如下:

Assembly asm = Assembly.LoadFile(“xxxxx”)

       asm.CreateInstance("MyAssembly.ClassName").GetType().InvokeMember("Say", BindingFlags.InvokeMethod, null, asm.CreateInstance("MyAssembly.ClassName "), new string[] { "aaa" });

 

这里顺便简略说一下反射流程:首先通过绝对路径加载某个NET的dll文件,然后创建该assembly中某个class的instance(该class必须有无参构造函数),获取其类型之后动态调用其函数Say,“BindingFlags.InvokeMethod”表明是一个普通类方法,“null”的地方是传递一个参数名的,和指明最后的string[]中的一串values内容一一匹配的……可见使用反射调用函数是很痛苦的一件事情。

现在呢?您根本不需要那么麻烦了!因为C#的dynamic会为您做好一切的,下面就是见证奇迹的时刻——

Assembly asm = Assembly.LoadFile("xxxxx");

dynamic dfun = asm.CreateInstance("MyAssembly.ClassName");

dfun.Say("Hello!");

 

            注意到咖啡色的代码了么——什么?dynamic竟然可以智能感知出动态加载的那个类的方法Say?其实不然:当你按下这个点的时候,IDE是没有智能感知的,但是如果你知道这个类是有这个方法(因为接口给了其一个契约,必须实现接口中的方法;而接口的方法是公开的),你就可以完全不理会智能感知,照样写,照样编译通过运行。神奇吧!

            看到这里,你就不会认为dynamic和var是“差不多”的概念了(var无非是根据赋值的类型编译器自己判断;且var不能作为函数返回值类型,但是dynamic可以)。

            或许有人会疑问:dynamic可以完全替代类似像简单工厂、抽象工厂一类的东西了咯?我的理解是——不对!从上面的定义中可以得知:dynamic必须首先获取对象实例,然后动态反射是它做的事情;如果完全取代反射,实例也获取不到,如何反射呢?真是“巧妇难为无米之炊”啊!

            说道dynamic可以作为返回值,下面给出一个例子:

class DynamicClass

    {

        public int Num1 { get; set; }

        public int Num2 { get; set; }

 

        public DynamicClass(int n1, int n2)

        {

            Num1 = n1;

            Num2 = n2;

        }

 

        public dynamic DynamicAction

        { get; set; }

    }

 

            主函数注意咖啡色部分:

            static void Main(string[] args)

        {

            DynamicClass t = new DynamicClass(1, 2);

            t.DynamicAction = new Func<int, int, double>((x, y) => x + y);

            Console.WriteLine(t.DynamicAction.Invoke(t.Num1,t.Num2));

        }

 

            道理很简单:因为dynamic类型可以赋值任何东西(包括匿名委托),所以我创建了一个匿名委托给它。然后调用计算结果(匿名委托的调用使用Invoke,可以省略)。

            但是……dynamic不仅仅可以动态反射类方法和属性,还可以“空中楼阁”般动态地去创建一个类方法和属性,并且赋值,相信吗?这是第二话。


原创粉丝点击