2
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。有没有人有提示如何使这种类型安全?

4

3 回答 3

2

像这样的东西?

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);
        }
    }
}
于 2010-06-28T15:59:54.693 回答
1

您可以存储一个应该执行的委托,而不是将“需要完成的操作”存储为一对方法和一个应该使用反射传递给它的参数。最简单的方法是存储类型列表List<Action<Customer>>- 然后在ApplyChanges方法中,您可以迭代列表并运行所有操作。

如果您不使用 .NET 3.5 和 C# 3.0(它定义了一个通用委托Action并支持 lambda 表达式),您仍然可以在 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”的解决方案完全符合我的描述。

于 2010-06-28T16:00:47.133 回答
1

所以你想避免将方法名作为字符串传递?为什么不在 setter 中获取 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);
}
于 2010-06-28T16:02:31.353 回答