Сделайте так, чтобы вызов метода отражения был безопасным - PullRequest
2 голосов
/ 28 июня 2010
class CustomerMessage
{
    private string name;
    private Dictionary<MethodBase, object> changeTrackingMethods = 
        new Dictionary<MethodBase, object>();

    public int Id { get; set; }

    public string Name {
        get { return this.name; }
        set
        {
            this.name = value;
            this.PropertyChanged("SetName", value);
        }
    }

    private void PropertyChanged(string behaviorMethod, object value)
    {
        var method = typeof(Customer).GetMethod(behaviorMethod);
        this.changeTrackingMethods.Add(method, value);
    }

    public void ApplyChanges(Customer c)
    {
        foreach (var changedProperty in this.changeTrackingMethods)
            changedProperty.Key.Invoke(c, new object[] { 
                changedProperty.Value 
            });
    }
}

Как видите, я отслеживаю изменения в этом входящем сообщении, чтобы запустить изменения для другого объекта.Метод для запуска передается PropertyChanged в виде строки.У кого-нибудь есть совет, как я могу сделать этот тип безопасным?

Ответы [ 3 ]

2 голосов
/ 28 июня 2010

Как то так?

class CustomerMessage
{
    private string name;
    private List<Action<Customer>> changeTrackingMethods =
        new List<Action<Customer>>();

    public int Id { get; set; }

    public string Name {
        get { return this.name; }
        set
        {
            this.name = value;
            this.changeTrackingMethods.Add(c => { c.SetName(value) });
        }
    }

    public void ApplyChanges(Customer c)
    {
        foreach (var action in this.changeTrackingMethods)
        {
            action(c);
        }
    }
}
1 голос
/ 28 июня 2010

То есть вы хотите избежать передачи имени метода в виде строки?Почему бы не получить объект MethodBase в установщике?

public string Name {
    get { return this.name; }
    set
    {
        this.name = value;
        this.PropertyChanged(typeof(Customer).GetMethod(behaviorMethod), value);
    }
}

private void PropertyChanged(MethodBase method, object value)
{
    this.changeTrackingMethods.Add(method, value);
}
1 голос
/ 28 июня 2010

Вместо сохранения «операции, которая должна быть выполнена» в виде пары методов и аргумента, который должен быть передан ей с помощью Reflection, вы можете сохранить делегат, который должен быть выполнен. Самый простой способ сделать это - сохранить список типа List<Action<Customer>> - затем в методе ApplyChanges вы можете выполнить итерацию по списку и выполнить все действия.

Если вы не используете .NET 3.5 и C # 3.0 (который определяет универсальный делегат Action и поддерживает лямбда-выражения), вы все равно можете написать это в C # 2.0:

// you can define a delegate like this
delegate void UpdateCustomer(Customer c);

// and you could use anonymous methods 
// (instead of more recent lambda expressions)
list.Add(delegate (Customer c) { c.SetName("test"); });

РЕДАКТИРОВАТЬ: похоже, я медленнее писал код, но я оставлю это здесь в качестве объяснения - решение с помощью 'dtb' делает именно то, что я описал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...