我在C#中执行IDynamicMetaObjectProvider
的自定义实现,因为我需要比使用DynamicObject
更好的性能,并且我需要继承。我使用DynamicMetaObject
和BindSetMember
的自定义实现扩展BindGetMember
。我的问题是:
何时调用BindSetMember和BindGetMember以及何时使用缓存规则?即,什么是缓存配置?
从调试我的实现我理解,例如,为每个特定的BindSetMember
类,属性名称和参数类型调用IDynamicMetaObjectProvider
。但我还没有找到任何这方面的文件。此外,在下面的代码中BindSetMember
被调用两次,BindGetMember
被调用两次,而我希望每个被调用一次:
dynamic obj = new MyDynamicImplementation();
obj.Property = 0; // Calls BindSetMember
if (obj.Property != 0) {} // Calls BindGetMember
obj.Property++; // Calls BindGetMember, then BindSetMember
有人可以解释或提及解释上述问题的文件吗?
答案 0 :(得分:1)
一个简单而高级的解释是缓存是按类型和每个调用站点完成的。在上面的示例中,呼叫站点对应于代码行。因此,缓存不用于任何行。
使用缓存的一个示例是访问循环中的属性,例如:
for (int i = 0; i < 10; i++)
obj.Property = i;
在上面的示例中,绑定将在i = 0
时完成一次,然后缓存将用于接下来的9次调用。
使用缓存的更复杂的例子:
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());
}
}
在上面的示例中,obj
类型Class1
和i = 0
的绑定只会执行一次,然后缓存将用于其余的循环调用和{{ 1}}类型obj
和任何Class2
。
作为结论:
如果从不同代码行访问的属性或值的类型不同,则会调用i
和BindGetMethod
。