TransWikia.com

Зачем binder или объект связывателя нужен в общем?

Stack Overflow на русском Asked by Denis Bredun on November 10, 2021

Есть код:

using System.Dynamic;
 
class PersonObject : DynamicObject
{
    Dictionary<string, object> members = new Dictionary<string, object>();
 
    // установка свойства
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        members[binder.Name] = value;
        return true;
    }
    // получение свойства
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;
        if (members.ContainsKey(binder.Name))
        {
            result = members[binder.Name];
            return true;
        }
        return false;
    }
    // вызов метода
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        dynamic method = members[binder.Name];
        result = method((int)args[0]);
        return result != null;
    }
}

Тут binder используется для обращения по имени к свойствам и методам. Так вот вопрос: кроме этого, он для чего-то ещё предназначен? Если да, то для чего? Где binder’ы можно использовать ещё, кроме работы с динамическими объектами?
Потом мне интересна логика по которой компилятор определяет обращения к методам определенных в классе PersonObject . Как он понимает, что строка person.Name = "Tom"; вызывает метод TrySetMember () и почему нельзя в привычной манере передать в ф-цию с параметрами, допустим так TrySetMember (SetMemberBinder binder=Name,object value=Tom), Тоже самое касается логики определения компилятора запуск метода TryGetMember, TryInvokeMember на основании выражение return person.Age и person.IncrementAge(4) соответственно.

One Answer

binder ... для чего-то ещё предназначен?

Этот класс предназначен именно для этого сценария - работа с DynamicObject.
В каких-нибудь библиотеках могут быть свои байндеры.

Как он понимает, что строка person.Name = "Tom"; вызывает метод TrySetMember()

Это зашито в компилятор. На этапе разбора кода C# парсер, встречая тип, производный от DynamicObject, преобразует эту строку в код, который создаёт и заполняет экземпляр байндера и подаёт его на вход этому методу

// create SetMemberBinder
// set binder.Name = "Name"
TrySetMember(binder, "Tom")

и почему нельзя в привычной манере передать в ф-цию

У вас есть возможность вклиниться в этап лексического разбора и генерации IL-кода?


Неясна суть ваших вопросов. Вам же не надо вручную создавать и заполнять эти байндеры. Этим занимаются лексер/парсер/компилятор. Вы просто пишете person.Age = 33. Всё!

Answered by Alexander Petrov on November 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP