Question

I do a custom implementation of IDynamicMetaObjectProvider in C#, since I need better performance than it is possible to achieve with DynamicObject and I need inheritance. I extend DynamicMetaObject with custom implementations of BindSetMember and BindGetMember. My question is:

When are BindSetMember and BindGetMember called and when are cached rules used? I.e., what is the cache configuration?

From debugging my implementation I understood that, e.g., BindSetMember is called for each specific IDynamicMetaObjectProvider class, property name and argument type. But I have not found any documentation of this. Furthermore, in the following code BindSetMember is called two times and BindGetMember is called two times, while I expect that each of them is called once:

dynamic obj = new MyDynamicImplementation();
obj.Property = 0; // Calls BindSetMember
if (obj.Property != 0) {} // Calls BindGetMember
obj.Property++; // Calls BindGetMember, then BindSetMember

Can anyone explain or give reference to documentation where my above questions are explained?

Was it helpful?

Solution

A simple and high-level explanation is that the cache is done per type and per call site. In the above example, call sites correspond to code lines. Thus the cache is not used for any of the lines.

An example of using cache is accessing a property in a loop such as:

for (int i = 0; i < 10; i++)
    obj.Property = i;

In the above example binding will be done once, when i = 0, and then cache will be utilized for next 9 calls.

More complex example of using cache:

public class Class1 : MyDynamicImpelementation {}
public class Class2 : MyDynamicImpelementation {}

static class Class
{
    public void PropertyAccess(dynamic obj)
    {
        for (int i = 0; i < 10; i++)
            obj.Property = i;
    }

    public void Main(string[] args)
    {
        PropertyAccess(new Class1());
        PropertyAccess(new Class2());
    }
}

In the above example binding will be done only once for obj of type Class1 and i = 0, then the cache will be used for the rest of the loop calls and for obj of type Class2 and any i.

As conclusion: BindGetMethod and BindSetMethod are called if a property accessed from different lines of code or if the type of a value is different.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top