Skip to content

dynamic object conventions

Stéphane Lozier edited this page Jan 18, 2021 · 1 revision

5 Dynamic Object Conventions

As a language implementer or library author, you may use the mechanisms described above to expose whatever arbitrary binding semantics you wish, including semantics that differ greatly from those of the language consuming your objects. The fallback system exposed by the DynamicMetaObjectBinder subclasses enables your objects to blend their semantics naturally with those of the language consuming them.

In addition to the fallback system, there are also some established conventions for dynamic interop that allow consuming languages to learn about the state of your objects in a standard way. By following these conventions, you can expose concepts such as enumerability or disposability in a way that can change at runtime.

5.1 Enumerability

An object that represents a sequence of other objects is considered to be enumerable. Enumerable objects may then be enumerated over in a language such as C# that supports “foreach” blocks, yielding each element in its sequence in turn.

In the static .NET world, objects are known to be enumerable if they implement the IEnumerable or IEnumerable<T> interface. This interface promises that your object implements a GetEnumerator method that returns an IEnumerator object, which can be used to move through your sequence. If you’re implementing an object library and know that a given class is always enumerable, the easiest way to specify enumerability is simply to implement IEnumerable<T> as normal.

However, you may be implementing library or language objects which are only sometimes enumerable, or which may become enumerable over time due to some dynamic operation on the object's type or itself. For example, in Python an object specifies that it is enumerable by defining an __iter__ method. Since this method may be added dynamically at runtime, the IronPython compiler cannot know whether to implement the IEnumerable interface on the objects it produces.

For these dynamic situations, an object may instead specify enumerability by binding a dynamic conversion to the IEnumerable type, succeeding if the object is indeed enumerable. Languages such as C# will first attempt to convert dynamic objects being “foreached” to the IEnumerable interface using a Convert call site.

Note that if the IEnumerator object you return from GetEnumerator is itself disposable, this object should implement IDisposable statically.

5.2 Disposability

An object that has resources to release when the object is no longer required is considered to be disposable. Disposable objects offer a .Dispose method to call when the object is to be released, but more often the calling language will provide some sort of “using” block which will automatically call an object’s Dispose method when the block completes.

Similar to enumerability, objects may statically specify that they are disposable by implementing the IDisposable interface, and this is the most straightforward approach if given classes in your object library always require disposing.

If your objects can become disposable at runtime, you may encode this in a similar fashion to enumerability, by successfully binding dynamic conversions to IDisposable. Languages such as C# using a dynamic object in a context that requires disposal will first attempt to dynamically convert the object to the IDisposable interface with a Convert call site.

Sites, Binders, and Dynamic Object Interop Spec

Frontmatter
1 Introduction
  1.1 Performance
  1.2 Language Interop
2 Dynamic Call Sites
  2.1 Rules
  2.2 CallSiteBinder
  2.3 CallSite<T>
    2.3.1 L0 Cache: CallSite’s Target Delegate
    2.3.2 L1 Cache: CallSite’s Rule Set
    2.3.3 L2 Cache: Combined Rule Sets of All Equivalent CallSites
    2.3.4 Other Optimizations
3 IDynamicMetaObjectProvider and DynamicMetaObject
  3.1 IDynamicMetaObjectProvider
  3.2 DynamicMetaObject
  3.3 DynamicMetaObjectBinder
    3.3.1 Fallback Methods – Implementing the Language’s Semantics
    3.3.2 Error Suggestions
  3.4 Dynamic Binding Walkthroughs
    3.4.1 a + b
    3.4.2 a.Foo(b)
4 DynamicObject and ExpandoObject
  4.1 DynamicObject
  4.2 ExpandoObject
  4.3 Further Reading
5 Dynamic Object Conventions
  5.1 Enumerability
  5.2 Disposability
6 API Reference
  6.1 DynamicMetaObject Class
    6.1.1 Class Summary
    6.1.2 Bind**Operation** Methods
    6.1.3 Expression Property
    6.1.4 Restrictions Property
    6.1.5 Value and HasValue Properties
    6.1.6 LimitType Property
    6.1.7 Create Static Method
    6.1.8 GetDynamicMemberNames Method
  6.2 IDynamicMetaObjectProvider Interface
    6.2.1 Class Summary
    6.2.2 GetMetaObject Method
  6.3 CallSiteBinder Abstract Class
    6.3.1 Class Summary
    6.3.2 Bind Method
    6.3.3 BindDelegate Method
    6.3.4 CacheTarget Method
    6.3.5 UpdateLabel Static Property
  6.4 DynamicMetaObjectBinder Abstract Class
    6.4.1 Fallback Methods
    6.4.2 Placing Canonical Binders on CallSites
    6.4.3 COM Support
    6.4.4 Class Summary
    6.4.5 Bind Method
    6.4.6 Defer Method
    6.4.7 ReturnType Property
    6.4.8 GetUpdateExpression Method
  6.5 GetMemberBinder Abstract Class
    6.5.1 Class Summary
    6.5.2 Name Property
    6.5.3 IgnoreCase Property
  6.6 SetMemberBinder Abstract Class
    6.6.1 Class Summary
    6.6.2 Name Property
    6.6.3 IgnoreCase Property
  6.7 DeleteMemberBinder Abstract Class
    6.7.1 Class Summary
    6.7.2 Name Property
    6.7.3 IgnoreCase Property
  6.8 GetIndexBinder Abstract Class
    6.8.1 Class Summary
    6.8.2 Calllnfo Property
  6.9 SetIndexBinder Abstract Class
    6.9.1 Class Summary
    6.9.2 Calllnfo Property
  6.10 DeleteIndexBinder Abstract Class
    6.10.1 Class Summary
    6.10.2 Calllnfo Property
  6.11 InvokeBinder Abstract Class
    6.11.1 Class Summary
    6.11.2 Calllnfo Property
  6.12 InvokeMemberBinder Abstract Class
    6.12.1 Class Summary
    6.12.2 Name Property
    6.12.3 IgnoreCase Property
    6.12.4 Calllnfo Property
    6.12.5 FallbackInvoke Method
  6.13 CreateInstanceBinder Abstract Class
    6.13.1 Class Summary
    6.13.2 Calllnfo Property
  6.14 ConvertBinder Abstract Class
    6.14.1 Class Summary
    6.14.2 Type Property
    6.14.3 Explicit Property
  6.15 UnaryOperationBinder Abstract Class
    6.15.1 Class Summary
    6.15.2 Operation Property
  6.16 BinaryOperationBinder Abstract Class
    6.16.1 Class Summary
    6.16.2 Operation Property
  6.17 CallInfo Class
    6.17.1 Class Summary
    6.17.2 ArgumentCount Property
    6.17.3 ArgumentNames Property
  6.18 BindingRestrictions Class
    6.18.1 Class Summary
    6.18.2 GetTypeRestriction Method
    6.18.3 GetInstanceRestriction Method
    6.18.4 GetExpressionRestriction Method
    6.18.5 Merge Method
    6.18.6 Combine Static Method
  6.19 CallSite and CallSite<T> Classes
    6.19.1 Class Summary
    6.19.2 Create Static Method
    6.19.3 Target Field
    6.19.4 Update Property
  6.20 StrongBox Class
    6.20.1 Class Summary
  6.21 DynamicObject Class
    6.21.1 Class Summary
  6.22 ExpandoObject Class
    6.22.1 Class Summary


Other documents:

Dynamic Language Runtime
DLR Hostirng Spec
Expression Trees v2 Spec
Getting Started with the DLR as a Library Author
SymPL Implementation on the Dynamic Language Runtime

Clone this wiki locally