DynamicObject类使开发人员能够实现动态类型或在运行时动态行为。开发人员无法直接创建此类的实例。相反,他需要扩展类以使其具有所需的行为。例如,对于具有动态行为的类,请参见下面的最小步骤,以创建和使用属性和方法。
dynamic d; // defines field d as dynamic and the type of the d determines at runtime d = 10; // at runtime, type of the d resolved as Int.32创建一个类并使用DynamicObject进行扩展。
class Employee : DynamicObject // create a class and extend with DynamicObject { private IDictionary<string, object=""> _members = new Dictionary<string, object="">(); }定义一个字典来存储动态对象,例如方法,属性及其值。
class Employee : DynamicObject // create a class and extend with DynamicObject { private IDictionary<string, object=""> _members = new Dictionary<string, object=""<(); }TrySetMember提供创建方法,属性及其值的实现。例如,设置employee类的属性或方法,如下:
employee.Id = 1007; // create a property Id and assign value 1007 at runtime employee.GetSalary = (Action)(() => { Console.WriteLine("Method is Invoked"); }); // Create a method GetSalary at runtime.然后,重写DynamicObject的TrySetMember方法。在我们的示例实现中,TrySetMember方法在运行时为行employee.Id = 1007创建属性'Id'并赋值1007。
class Employee: DynamicObject // create a class and extend with DynamicObject { private IDictionary<string, object=""> _members = new Dictionary<string, object="">(); public override bool TrySetMember(SetMemberBinder binder, object value) { _members[binder.Name] = value; return true; } } class Program { static void Main(string[] args) { dynamic employee = new Employee(); employee.Id = 1007; // create a property Id and assign value 1007 at runtime employee.Name = "Bhupathi"; // create a property Name // and assign value "Bhupathi" at runtime employee.GetSalary = (Action)(() => { Console.WriteLine("Method is Invoked"); }); // Create a method GetSalary at runtime Console.ReadKey(); } }TrySetMember参数
Binder 提供有关正在尝试设置值的对象的信息。binder.Name属性提供成员的名称。Result 是要为动态对象设置的值。Returns true如果操作成功;否则为falseTryGetMember提供实现以获取属性的值。例如,var当我们尝试访问时employee.Id,DLR使用语言绑定程序查找静态定义。如果没有属性,则DLR调用TryGetMember。
class Employee: DynamicObject // create a class and extend with DynamicObject { private IDictionary<string, object=""> _members = new Dictionary<string, object="">(); public override bool TrySetMember(SetMemberBinder binder, object value) {...} public override bool TryGetMember(GetMemberBinder binder, out object result) { return _members.TryGetValue(binder.Name, out result); } } class Program { static void Main(string[] args) { dynamic employee = new Employee(); employee.Id = 1007; // create a property Id and assign value 1007 at runtime employee.Name = "Bhupathi"; // create a property Name and // assign value "Bhupathi" at runtime employee.GetSalary = (Action)(() => { Console.WriteLine("Method is Invoked"); }); // Create a method // GetSalary at runtime Console.WriteLine("List of values in employee object"); Console.WriteLine($"Employee Id : {employee.Id}"); // retrieves the value of property id in employee object Console.WriteLine($"Employee Name : {employee.Name}"); // retrieves the value // of property Name in // employee object Console.ReadKey(); } }在我们的示例行int eid = employee.Id中,TryGetMember返回Id的值。
TryGetMember参数
Binder提供有关试图检索该值的对象的信息。binder.Name属性提供成员的名称。Result 是尝试检索值的动态对象的返回值。Returns true如果操作成功;否则为false。TryInvokeMember 提供调用方法的实现。
class Employee: DynamicObject // create a class and extend with DynamicObject { private IDictionary<string, object=""> _members = new Dictionary<string, object="">(); public override bool TrySetMember(SetMemberBinder binder, object value) {...} public override bool TryGetMember(GetMemberBinder binder, out object result) {...} public override bool TryInvokeMember (InvokeMemberBinder binder, object[] args, out object result) { Type dictType = typeof(Dictionary<string, object="">); try { result = dictType.InvokeMember( binder.Name, BindingFlags.InvokeMethod, null, _members, args); return true; } catch { return false; } } } class Program { static void Main(string[] args) { dynamic employee = new Employee(); employee.GetSalary = (Action)(() => { Console.WriteLine("Method is Invoked"); }); // Create a method // GetSalary at runtime employee.GetSalary(); Console.ReadKey(); } }在我们的示例中,employee.GetSalary(); GetSalary方法将与null参数一起调用。
TryInvokeMember参数
Binder提供有关正在尝试调用的对象或方法的信息。binder.Name属性提供成员的名称。Args[] 与方法一起传递的参数Result 执行后从方法返回的值Returns true如果操作成功;否则为falseExpandoObject是IDynamicMetaObjectProvider的全部功能的类和实现,其也是.NET的动态库的一部分。当您不需要动态类的任何自定义行为时,ExpandoObject非常有用。
动态对象在运行时发出代码,并且非常昂贵。除非需要,否则不要使用动态对象,例如使用COM API(例如Office API)。
