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