C#4.0新特性(1):Dynamic Lookup 动态查找
C# 4.0的主要主题是动态编程。对象的意义变得越来越“动态”,它们的结构和行为无法通过静态类型来捕获,或者至少编译器在编译程序时无法得知对象的结构和行为。例如——
•a. 来自动态编程语言——如Python或Ruby——的对象
•b. 通过IDispatch访问的COM对象
•c. 通过反射访问的一般.NET类型
•d. 结构发生过变化的对象——如HTML DOM对象
动态查找允许在编写方法、运算符和索引器调用、属性和字段访问甚至对象调用时,绕过C#静态类型检查,而在运行时进行解析。
动态查找允许动态(即在运行时)实现对某个对象的操作与对象类型的绑定,而不管这个对象是来自COM,IronPython,HTML DOM还是CLR的反射。你可以在程序中绕过编译器的类型检查,而把类型的匹配(lookup)丢给运行时去作。如果你需要对这样的对象进行操作,则会用到一个全新的类型:dynamic。
dynamic类型(The dynamic type)
C# 4.0引入了一个新的静态类型,称为dynamic。当你拥有了一个dynamic类型的对象后,你“对他做的事情”只会在运行时进行解析——
1 dynamic d = GetDynamicObject(...);
2 d.M(7);
C#编译器允许你使用任何参数在d上调用一个方法,因为它的类型是dynamic。运行时会检查d的实际类型,并检测在它上面“用一个int调用M”是什么意思。
可以认为dynamic类型是object类型的一个特殊版本,指出了对象可以动态地使用。选择是否使用动态行为很简单——任何对象都可以隐式转换为dynamic,“挂起信任”直到运行时。反之,从dynamic到任何其他类型都存在“赋值转换”,可以类似于赋值的结构中进行隐式转换——
1 dynamic d = 7; // implicit conversion
2 int i = d; // assignment conversion
动态操作(Dynamic operations)
不仅是方法调用,字段和属性访问、索引器和运算符调用甚至委托调用都可以动态地分派——
1 dynamic d = GetDynamicObject(…);
2 d.M(7); // calling methods
3 d.f = d.P; // getting and settings fields and properties
4 d[“one”] = d[“two”]; // getting and setting thorugh indexers
5 int i = d + 3; // calling operators
6 string s = d(5,7); // invoking as a delegate
01 class Program
02 {
03 static void Main(string[] args)
04 {
05 dynamic dyn = 1;
06 object obj = 1;
07
08 // Rest the mouse pointer over dyn and obj to see their
09 // types at compile time.
10 System.Console.WriteLine(dyn.GetType());
11 System.Console.WriteLine(obj.GetType());
12 }
13 }
程序输出为:
1 System.Int32
2
3 System.Int32
dynamic关键字还可以作为类型的属性、字段、索引器、参数、返回值、局部变量和类型约束。请看下面示例:
01 class ExampleClass
02 {
03 // A dynamic field.
04 static dynamic field;
05
06 // A dynamic property.
07 dynamic prop { get; set; }
08
09 // A dynamic return type and a dynamic paramater type.
10 public dynamic exampleMethod(dynamic d)
11 {
12 // A dynamic local variable.
13 dynamic local = "Local variable";
14 int two = 2;
15
16 if (d is int)
17 {
18 return local;
19 }
20 else
21 {
22 return two;
23 }
24 }
25 }
还可以作为显式类型转换中的目标类型,如下:
01 static void convertToDynamic()
02 {
03 dynamic d;
04 int i = 20;
05 d = (dynamic)i;
06 Console.WriteLine(d);
07
08 string s = "Example string.";
09 d = (dynamic)s;
10 Console.WriteLine(d);
11
12 DateTime dt = DateTime.Today;
13 d = (dynamic)dt;
14 Console.WriteLine(d);
15
16 }
17 // Results:
18 // 20
19 // Example string.
20 // 2/17/2009 9:12:00 AM
还可以用于is、as和typeof运算符:
01 int i = 8;
02 dynamic d;
03 // With the is operator.
04 // The dynamic type behaves like object. The following
05 // expression returns true unless someVar has the value null.
06 if (someVar is dynamic) { }
07
08 // With the as operator.
09 d = i as dynamic;
10
11 // With typeof, as part of a constructed type.
12 Console.WriteLine(typeof(List<dynamic>));
13
14 // The following statement causes a compiler error.
15 //Console.WriteLine(typeof(dynamic));
类型转换:
1 dynamic d1 = 7;
2 dynamic d2 = "a string";
3 dynamic d3 = System.DateTime.Today;
4 dynamic d4 = System.Diagnostics.Process.GetProcesses();
1 int i = d1;
2 string str = d2;
3 DateTime dt = d3;
4 System.Diagnostics.Process[] procs = d4;
完整示例如下:
01 using System;
02
03 namespace DynamicExamples
04 {
05 class Program
06 {
07 static void Main(string[] args)
08 {
09 ExampleClass ec = new ExampleClass();
10 Console.WriteLine(ec.exampleMethod(10));
11 Console.WriteLine(ec.exampleMethod("value"));
12
13 // The following line causes a compiler error because exampleMethod
14 // takes only one argument.
15 //Console.WriteLine(ec.exampleMethod(10, 4));
16
17 dynamic dynamic_ec = new ExampleClass();
18 Console.WriteLine(dynamic_ec.exampleMethod(10));
19
20 // Because dynamic_ec is dynamic, the following call to exampleMethod
21 // with two arguments does not produce an error at
补充:软件开发 , C# ,