Конфигурация кэша связующего для DynamicMetaObject в C # - PullRequest
1 голос
/ 22 декабря 2011

Я делаю пользовательскую реализацию IDynamicMetaObjectProvider в C #, так как мне нужна лучшая производительность, чем это возможно при 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

Может кто-нибудь объяснить или дать ссылку на документациюгде мои вышеперечисленные вопросы объясняются?

1 Ответ

1 голос
/ 27 декабря 2011

Простое и высокоуровневое объяснение состоит в том, что кэш создается для каждого типа и для каждого сайта вызова. В приведенном выше примере сайты вызовов соответствуют строкам кода. Таким образом, кеш не используется ни для одной из строк.

Примером использования кэша является обращение к свойству в цикле, например:

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, затем кеш будет использоваться для остальных вызовов цикла и для obj типа Class2 и любой i.

В качестве заключения: BindGetMethod и BindSetMethod вызываются, если свойство доступно из разных строк кода или тип значения отличается.

...