DynamicObject 类 |
提供用于指定运行时的动态行为的基类。必须继承此类;不能直接实例化此类。
程序集: System.Core(在 System.Core.dll 中)
Public Class DynamicObject _ Implements IDynamicMetaObjectProvider
Public Class DynamicObject _ Implements IDynamicMetaObjectProvider
public class DynamicObject : IDynamicMetaObjectProvider
public class DynamicObject : IDynamicMetaObjectProvider
public ref class DynamicObject : IDynamicMetaObjectProvider
public ref class DynamicObject : IDynamicMetaObjectProvider
type DynamicObject = class interface IDynamicMetaObjectProvider end
type DynamicObject = class interface IDynamicMetaObjectProvider end
DynamicObject 类使您能够定义可以动态对象上执行哪些操作以及如何执行这些操作。 例如,可以定义当尝试获取或设置对象属性、调用一个方法或执行标准的数学运算(如加法和乘法)时将发生的情况。
如果要为库创建更方便的协议,此类可能非常有帮助。例如,如果库用户必须使用 Scriptobj.SetProperty("Count",1) 这样的语法,您可以允许使用更简单的语法,如 scriptobj.Count = 1。
无法直接创建 DynamicObject 类的实例。 若要实现动态行为,您可能需要继承自 DynamicObject 类并重写必要方法。 例如,如果只需要设置和获取属性的操作,您可以只覆盖 TrySetMember 和 TryGetMember 方法。
在 C# 中,要为从 DynamicObject 类派生的类实例启用动态行为,必须使用 dynamic 关键字。 有关更多信息,请参见 使用类型 dynamic(C# 编程指南)。
在 Visual Basic 中,后期绑定支持动态操作。有关更多信息,请参见 早期绑定和后期绑定。
下面的代码示例演示如何创建从 DynamicObject 类派生的类的实例。
Public Class SampleDynamicObject Inherits DynamicObject '...Dim sampleObject As Object = New SampleDynamicObject()
Public Class SampleDynamicObject Inherits DynamicObject '...Dim sampleObject As Object = New SampleDynamicObject()
public class SampleDynamicObject : DynamicObject {} //...dynamic sampleObject = new SampleDynamicObject ();
public class SampleDynamicObject : DynamicObject {} //...dynamic sampleObject = new SampleDynamicObject ();
也可以将自己的成员添加到从 DynamicObject 类派生的类。 如果您的类定义了属性,并且还重写 TrySetMember 方法,动态语言运行库 (DLR) 将首先使用语言联编程序在类中查找属性的静态定义。 如果没有此类属性,DLR 调用 TrySetMember 方法。
DynamicObject 类实现 DLR 接口 IDynamicMetaObjectProvider,使您可以在支持 DLR 互操作性模型的各种语言之间共享 DynamicObject 类的实例。 例如,您可以在 C# 中创建 DynamicObject 类的实例,然后将它传递给 IronPython 函数。 有关更多信息,请参见 动态语言运行时概述和 CodePlex 网站上的相关文档。
说明 |
---|
如果在简单方案中需要只能在运行时添加和删除成员但不需要定义特定操作并且没有静态成员的对象时,请使用 ExpandoObject 类。 如果在较高级方案中需要定义动态对象如何参与互操作性协议,或者需要管理 DLR 快速动态调度缓存,请创建您自己的 IDynamicMetaObjectProvider 接口实现。 |
假定您要提供访问字典中的值的替代语法,这样就不需要编写 sampleDictionary["Text"] = "Sample text"(在 Visual Basic 中为 sampleDictionary("Text") = "Sample text"),您可以编写 sampleDictionary.Text = "Sample text"。 此外,该语法应该不区分大小写,以便 sampleDictionary.Text 等效于 sampleDictionary.text。
下面的代码示例演示如何实现从 DynamicObject 类派生的 DynamicDictionary 类。 DynamicDictionary 类包含 Dictionary<string,object> 类型(在 Visual Basic 中为 Dictionary(Of String,Object))的对象来存储键-值对,并且重写 TrySetMember 和 TryGetMember 方法来支持新语法。 它还提供了 Count 属性,显示在词典中包含的动态属性数量。
' The class derived from DynamicObject. Public Class DynamicDictionary Inherits DynamicObject ' The inner dictionary. Dim dictionary As New Dictionary(Of String,Object) ' This property returns the number of elements ' in the inner dictionary. ReadOnly Property Count As Integer Get Return dictionary.Count End Get End Property ' If you try to get a value of a property that is ' not defined in the class,this method is called. Public Overrides Function TryGetMember( ByVal binder As System.Dynamic.GetMemberBinder,ByRef result As Object) As Boolean ' Converting the property name to lowercase ' so that property names become case-insensitive. Dim name As String = binder.Name.ToLower() ' If the property name is found in a dictionary,' set the result parameter to the property value and return true. ' Otherwise,return false. Return dictionary.TryGetValue(name,result) End Function Public Overrides Function TrySetMember( ByVal binder As System.Dynamic.SetMemberBinder,ByVal value As Object) As Boolean ' Converting the property name to lowercase ' so that property names become case-insensitive. dictionary(binder.Name.ToLower()) = value ' You can always add a value to a dictionary,' so this method always returns true. Return True End Function End Class Sub Main() ' Creating a dynamic dictionary. Dim person As Object = New DynamicDictionary() ' Adding new dynamic properties. ' The TrySetMember method is called. person.FirstName = "Ellen" person.LastName = "Adams" ' Getting values of the dynamic properties. ' The TryGetMember method is called. ' Note that property names are now case-insensitive,' although they are case-sensitive in C#. Console.WriteLine(person.firstname & " " & person.lastname) ' Getting the value of the Count property. ' The TryGetMember is not called,' because the property is defined in the class. Console.WriteLine("Number of dynamic properties:" & person.Count) ' The following statement throws an exception at run time. ' There is no "address" property,' so the TryGetMember method returns false and this causes ' a MissingMemberException. ' Console.WriteLine(person.address) End Sub ' This examples has the following output: ' Ellen Adams ' Number of dynamic properties: 2