Sdílet prostřednictvím


DynamicObject Class

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Provides a base class for specifying dynamic behavior at run time. This class must be inherited from; you cannot instantiate it directly.

Inheritance Hierarchy

System.Object
  System.Dynamic.DynamicObject

Namespace:  System.Dynamic
Assembly:  System.Core (in System.Core.dll)

Syntax

'Declaration
Public Class DynamicObject _
    Implements IDynamicMetaObjectProvider
public class DynamicObject : IDynamicMetaObjectProvider

The DynamicObject type exposes the following members.

Constructors

  Name Description
Protected method DynamicObject Enables derived types to initialize a new instance of the DynamicObject type.

Top

Methods

  Name Description
Public method Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected method Finalize Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)
Public method GetDynamicMemberNames Returns the enumeration of all dynamic member names.
Public method GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public method GetMetaObject Provides a DynamicMetaObject that dispatches to the dynamic virtual methods. 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.
Public method GetType Gets the Type of the current instance. (Inherited from Object.)
Protected method MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Public method ToString Returns a string that represents the current object. (Inherited from Object.)
Public method TryBinaryOperation Provides implementation for binary operations. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as addition and multiplication.
Public method TryConvert Provides implementation for type conversion operations. 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.
Public method TryCreateInstance Provides the implementation for operations that initialize a new instance of a dynamic object. This method is not intended for use in C# or Visual Basic.
Public method TryDeleteIndex Provides the implementation for operations that delete an object by index. This method is not intended for use in C# or Visual Basic.
Public method TryDeleteMember Provides the implementation for operations that delete an object member. This method is not intended for use in C# or Visual Basic.
Public method TryGetIndex Provides the implementation for operations that get a value by index. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for indexing operations.
Public method TryGetMember Provides the implementation for operations that get member values. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as getting a value for a property.
Public method TryInvoke Provides the implementation for operations that invoke an object. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as invoking an object or a delegate.
Public method TryInvokeMember Provides the implementation for operations that invoke a member. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as calling a method.
Public method TrySetIndex Provides the implementation for operations that set a value by index. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations that access objects by a specified index.
Public method TrySetMember Provides the implementation for operations that set member values. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as setting a value for a property.
Public method TryUnaryOperation Provides implementation for unary operations. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as negation, increment, or decrement.

Top

Remarks

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. For 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.

You cannot directly create an instance of the DynamicObject class. To implement the dynamic behavior, you may want to inherit from the DynamicObject class and override necessary methods. For example, if you need only operations for setting and getting properties, you can override just the TrySetMember and TryGetMember methods.

In C#, to enable dynamic behavior for instances of classes derived from the DynamicObject class, you must use the dynamic keyword.

In Visual Basic, dynamic operations are supported by late binding.

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()

You can also add your own members to classes derived from the DynamicObject class. 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. If there is no such property, the DLR calls the TrySetMember method.

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. 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 documentation on the CodePlex Web site.

NoteNote:

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.

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.

Examples

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". Also, you want this syntax to be case-insensitive, so that sampleDictionary.Text is equivalent to sampleDictionary.text.

The following code example demonstrates the DynamicDictionary class, which is derived from the DynamicObject class. 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. It also provides a Count property, which shows how many dynamic properties the dictionary contains.

' 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 Demo(outputBlock As System.Windows.Controls.TextBlock)
    ' 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#.
    outputBlock.Text &= person.firstname & " " & person.lastname & vbCrLf

    ' Getting the value of the Count property.
    ' The TryGetMember is not called, 
    ' because the property is defined in the class.
    outputBlock.Text &= "Number of dynamic properties:" & person.Count & vbCrLf

    ' 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.
    ' outputBlock.Text &= person.address & vbCrLf
End Sub
' This examples has the following output:
' Ellen Adams
' Number of dynamic properties: 2
// 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 Example
{
   private static System.Windows.Controls.TextBlock outputBlock;

   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {

      Example.outputBlock = outputBlock;
      // 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.
      outputBlock.Text += person.firstname + " " + person.lastname + "\n";

      // Getting the value of the Count property.
      // The TryGetMember is not called, 
      // because the property is defined in the class.
      outputBlock.Text +=
          "Number of dynamic properties:" + person.Count + "\n";

      // 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.
      // outputBlock.Text += person.address + "\n";
   }
}

// This example has the following output:
// Ellen Adams
// Number of dynamic properties: 2

For more examples, see Creating Wrappers with DynamicObject on the C# Frequently Asked Questions blog.

Version Information

Silverlight

Supported in: 5, 4

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

See Also

Reference