(一)DLR
C#4的动态功能是Dynamic Language Runtime(动态语言运行时,DLR)的一部分。DLR是添加到CLR的一系列服务。
(二)dynamic类型
dynamic类型允许编写忽略编译期间的类型检查的代码。编译器假定,给dynamic类型的对象定义的任何操作都是有效的,在运行之前编译器不会检测是否存在错误。
例子:
dynamic person = "人"; string firstName = person.FirstName;
这两行代码能够通过编译器编译,但是点击运行后会报错:
需要注意的是,dynamic类型虽然很有用,但是它是有代价的。
(三)包含DLR ScriptRuntime
给应用程序添加脚本编辑功能,并给脚本传入数值和从脚本传出数值,是应用程序可以利用脚本完成工作。
(四)DynamicObject和ExpandoObject
从DynamicObject中派生或者使用ExpandoObject可以创建自己的动态对象。
使用DynamicObject派生创建动态对象,需要重写3个方法TrySetMembe()、TryGetMember()和TryInvokeMember()。
使用ExpandoObject与DynamicObject进行派生的区别在于不用重写方法。
例子:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Func<string, string, string> getFullName = (f, l) => { return f + " " + l; }; 6 dynamic byexobj = new ExpandoObject(); 7 byexobj.FirstName = "李"; 8 byexobj.LastName = "四"; 9 byexobj.GetFullName = getFullName; 10 Console.WriteLine(byexobj.GetType()); 11 Console.WriteLine(byexobj.GetFullName(byexobj.FirstName, byexobj.LastName)); 12 Console.WriteLine("====================="); 13 dynamic dyobj = new MyDynamicObject(); 14 dyobj.FirstName = "张"; 15 dyobj.LastName = "三"; 16 dyobj.GetFullName = getFullName; 17 Console.WriteLine(dyobj.GetType()); 18 Console.WriteLine(dyobj.GetFullName(dyobj.FirstName, dyobj.LastName)); 19 Console.ReadKey(); 20 } 21 } 22 23 public class MyDynamicObject : DynamicObject 24 { 25 Dictionary<string, object> dynamicData = new Dictionary<string, object>(); 26 public override bool TrySetMember(SetMemberBinder binder, object value) 27 { 28 dynamicData[binder.Name] = value; 29 return true; 30 } 31 public override bool TryGetMember(GetMemberBinder binder, out object result) 32 { 33 bool success = false; 34 result = null; 35 if (dynamicData.ContainsKey(binder.Name)) 36 { 37 result = dynamicData[binder.Name]; 38 success = true; 39 } 40 else 41 { 42 result = "未找到该属性的值"; 43 success = false; 44 } 45 return success; 46 } 47 public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) 48 { 49 dynamic method = dynamicData[binder.Name]; 50 result = method((string)args[0],(string)args[1]); 51 return result != null; 52 } 53 }
运行以上代码,结果如下: