DynamicObject 类

定义

提供用于在运行时指定动态行为的基类。Provides a base class for specifying dynamic behavior at run time. 必须继承此类;不能直接对其进行实例化。This class must be inherited from; you cannot instantiate it directly.

public ref class DynamicObject : System::Dynamic::IDynamicMetaObjectProvider
[System.Serializable]
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
type DynamicObject = class
    interface IDynamicMetaObjectProvider
Public Class DynamicObject
Implements IDynamicMetaObjectProvider
继承
DynamicObject
派生
属性
实现

示例

假设你想要提供用于访问字典中的值的替代语法,以便可以编写 sampleDictionary.Text = "Sample text",而不是编写 sampleDictionary["Text"] = "Sample text"sampleDictionary("Text") = "Sample text" 在 Visual Basic 中)。Assume that you want to provide alternative syntax for accessing values in a dictionary, so that instead of writing sampleDictionary["Text"] = "Sample text" (sampleDictionary("Text") = "Sample text" in Visual Basic), you can write sampleDictionary.Text = "Sample text". 此外,您希望此语法不区分大小写,以便 sampleDictionary.Text 等效于 sampleDictionary.textAlso, you want this syntax to be case-insensitive, so that sampleDictionary.Text is equivalent to sampleDictionary.text.

下面的代码示例演示 DynamicDictionary 类,该类派生自 DynamicObject 类。The following code example demonstrates the DynamicDictionary class, which is derived from the DynamicObject class. DynamicDictionary 类包含 Dictionary<string, object> 类型的对象(Visual Basic 中的Dictionary(Of String, Object))以存储键-值对,并重写 TrySetMemberTryGetMember 方法来支持新的语法。The DynamicDictionary class contains an object of the Dictionary<string, object> type (Dictionary(Of String, Object) in Visual Basic) to store the key-value pairs, and overrides the TrySetMember and TryGetMember methods to support the new syntax. 它还提供了一个 Count 属性,该属性显示字典包含的动态属性的数目。It also provides a Count property, which shows how many dynamic properties the dictionary contains.

// The class derived from DynamicObject.
public class DynamicDictionary : DynamicObject
{
    // The inner dictionary.
    Dictionary<string, object> dictionary
        = new Dictionary<string, object>();

    // This property returns the number of elements
    // in the inner dictionary.
    public int Count
    {
        get
        {
            return dictionary.Count;
        }
    }

    // If you try to get a value of a property 
    // not defined in the class, this method is called.
    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        // Converting the property name to lowercase
        // so that property names become case-insensitive.
        string name = 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, out result);
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        // 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;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Creating a dynamic dictionary.
        dynamic person = 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 case-insensitive.
        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
        // RuntimeBinderException.
        // Console.WriteLine(person.address);
    }
}

// This example has the following output:
// Ellen Adams
// Number of dynamic properties: 2
' 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

有关更多示例,请参阅C#常见问题博客上的创建包含 DynamicObject 的包装For more examples, see Creating Wrappers with DynamicObject on the C# Frequently Asked Questions blog.

注解

利用 DynamicObject 类,您可以定义可对动态对象执行哪些操作,以及如何执行这些操作。The DynamicObject class enables you to define which operations can be performed on dynamic objects and how to perform those operations. 例如,你可以定义当你尝试获取或设置对象属性、调用方法或执行标准数学运算(如加法和乘法)时所发生的情况。For example, you can define what happens when you try to get or set an object property, call a method, or perform standard mathematical operations such as addition and multiplication.

如果要为库创建更方便的协议,此类会很有用。This class can be useful if you want to create a more convenient protocol for a library. 例如,如果你的库用户必须使用类似 Scriptobj.SetProperty("Count", 1)的语法,则可以提供更简单的语法,如 scriptobj.Count = 1For example, if users of your library have to use syntax like Scriptobj.SetProperty("Count", 1), you can provide the ability to use much simpler syntax, like scriptobj.Count = 1.

不能直接创建 DynamicObject 类的实例。You cannot directly create an instance of the DynamicObject class. 若要实现动态行为,你可能想要从 DynamicObject 类继承并重写必要的方法。To implement the dynamic behavior, you may want to inherit from the DynamicObject class and override necessary methods. 例如,如果只需要用于设置和获取属性的操作,则可以只覆盖 TrySetMemberTryGetMember 方法。For example, if you need only operations for setting and getting properties, you can override just the TrySetMember and TryGetMember methods.

在C#中,若要为从 DynamicObject 类派生的类的实例启用动态行为,必须使用 dynamic 关键字。In C#, to enable dynamic behavior for instances of classes derived from the DynamicObject class, you must use the dynamic keyword. 有关更多信息,请参见使用类型 dynamicFor more information, see Using Type dynamic.

在 Visual Basic 中,后期绑定支持动态操作。In Visual Basic, dynamic operations are supported by late binding. 有关详细信息,请参阅早期和后期绑定For more information, see Early and Late Binding.

下面的代码示例演示如何创建派生自 DynamicObject 类的类的实例。The following code example demonstrates how to create an instance of a class that is derived from the DynamicObject class.

public class SampleDynamicObject : DynamicObject {}  
//...  
dynamic sampleObject = new SampleDynamicObject ();  
Public Class SampleDynamicObject   
    Inherits DynamicObject  
'...  
Dim sampleObject As Object = New SampleDynamicObject()  

你还可以将自己的成员添加到从 DynamicObject 类派生的类。You can also add your own members to classes derived from the DynamicObject class. 如果你的类定义了属性,并且还重写了 TrySetMember 方法,则动态语言运行时(DLR)首先使用语言联编程序在类中查找属性的静态定义。If your class defines properties and also overrides the TrySetMember method, the dynamic language runtime (DLR) first uses the language binder to look for a static definition of a property in the class. 如果没有此类属性,则 DLR 会调用 TrySetMember 方法。If there is no such property, the DLR calls the TrySetMember method.

DynamicObject 类实现了 DLR 接口 IDynamicMetaObjectProvider,使你能够在支持 DLR 互操作性模型的语言之间共享 DynamicObject 类的实例。The DynamicObject class implements the DLR interface IDynamicMetaObjectProvider, which enables you to share instances of the DynamicObject class between languages that support the DLR interoperability model. 例如,你可以在中C#创建 DynamicObject 类的实例,然后将其传递给 IronPython 函数。For example, you can create an instance of the DynamicObject class in C# and then pass it to an IronPython function. 有关详细信息,请参阅动态语言运行时概述For more information, see Dynamic Language Runtime Overview.

备注

如果你有一个简单的方案,在此方案中,你需要一个仅可在运行时添加和删除成员的对象,但这不需要定义特定操作,并且没有静态成员,请使用 ExpandoObject 类。If you have a simple scenario in which you need an object that can only add and remove members at run time but that does not need to define specific operations and does not have static members, use the ExpandoObject class.

如果你有一个更高级的方案,在此方案中,需要定义动态对象如何参与互操作性协议,或者需要管理 DLR 快速动态调度缓存,请创建你自己的 IDynamicMetaObjectProvider 接口实现。If you have a more advanced scenario in which you need to define how dynamic objects participate in the interoperability protocol, or you need to manage DLR fast dynamic dispatch caching, create your own implementation of the IDynamicMetaObjectProvider interface.

构造函数

DynamicObject()

使派生的类型可以初始化 DynamicObject 类型的新实例。Enables derived types to initialize a new instance of the DynamicObject type.

方法

Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
GetDynamicMemberNames()

返回所有动态成员名称的枚举。Returns the enumeration of all dynamic member names.

GetHashCode()

用作默认哈希函数。Serves as the default hash function.

(继承自 Object)
GetMetaObject(Expression)

提供调度到动态虚方法的 DynamicMetaObjectProvides a DynamicMetaObject that dispatches to the dynamic virtual methods. 可以将该对象封装到另一个 DynamicMetaObject 中,以便为各个不同操作提供自定义行为。The object can be encapsulated inside another DynamicMetaObject to provide custom behavior for individual actions. 此方法支持语言实现器的动态语言运行时基础结构,不应从代码直接使用。This method supports the Dynamic Language Runtime infrastructure for language implementers and it is not intended to be used directly from your code.

GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
ToString()

返回一个表示当前对象的 string。Returns a string that represents the current object.

(继承自 Object)
TryBinaryOperation(BinaryOperationBinder, Object, Object)

提供二元运算的实现。Provides implementation for binary operations. DynamicObject 类派生的类可以重写此方法,以便为诸如加法和乘法这样的运算指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as addition and multiplication.

TryConvert(ConvertBinder, Object)

提供类型转换运算的实现。Provides implementation for type conversion operations. DynamicObject 类派生的类可以重写此方法,以便为将某个对象从一种类型转换为另一种类型的运算指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations that convert an object from one type to another.

TryCreateInstance(CreateInstanceBinder, Object[], Object)

为初始化动态对象的新实例的操作提供实现。Provides the implementation for operations that initialize a new instance of a dynamic object. 不应将此方法用于 C# 或 Visual Basic。This method is not intended for use in C# or Visual Basic.

TryDeleteIndex(DeleteIndexBinder, Object[])

为按索引删除对象的操作提供实现。Provides the implementation for operations that delete an object by index. 不应将此方法用于 C# 或 Visual Basic。This method is not intended for use in C# or Visual Basic.

TryDeleteMember(DeleteMemberBinder)

为删除对象成员的操作提供实现。Provides the implementation for operations that delete an object member. 不应将此方法用于 C# 或 Visual Basic。This method is not intended for use in C# or Visual Basic.

TryGetIndex(GetIndexBinder, Object[], Object)

为按索引获取值的操作提供实现。Provides the implementation for operations that get a value by index. DynamicObject 类派生的类可以重写此方法,以便为索引操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for indexing operations.

TryGetMember(GetMemberBinder, Object)

提供用于获取成员值的操作的实现。Provides the implementation for operations that get member values. DynamicObject 类派生的类可以重写此方法,以便为诸如获取属性值这样的操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as getting a value for a property.

TryInvoke(InvokeBinder, Object[], Object)

为调用对象的操作提供实现。Provides the implementation for operations that invoke an object. DynamicObject 类派生的类可以重写此方法,以便为诸如调用对象或委托这样的操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate.

TryInvokeMember(InvokeMemberBinder, Object[], Object)

提供用于调用成员的操作的实现。Provides the implementation for operations that invoke a member. DynamicObject 类派生的类可以重写此方法,以便为诸如调用方法这样的操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as calling a method.

TrySetIndex(SetIndexBinder, Object[], Object)

为按索引设置值的操作提供实现。Provides the implementation for operations that set a value by index. DynamicObject 类派生的类可以重写此方法,以便为按指定索引访问对象的操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations that access objects by a specified index.

TrySetMember(SetMemberBinder, Object)

提供用于设置成员值的操作的实现。Provides the implementation for operations that set member values. DynamicObject 类派生的类可以重写此方法,以便为诸如设置属性值这样的操作指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as setting a value for a property.

TryUnaryOperation(UnaryOperationBinder, Object)

提供一元运算的实现。Provides implementation for unary operations. DynamicObject 类派生的类可以重写此方法,以便为诸如求反、递增、递减这样的运算指定动态行为。Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as negation, increment, or decrement.

适用于