質問

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に渡されます。誰かが私がこのタイプを安全にすることができる方法を持っていますか?

役に立ちましたか?

解決

このようなもの?

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);
        }
    }
}

他のヒント

メソッド名を文字列として渡すことを避けたいですか?メソッドベースオブジェクトをセッターに入手してみませんか?

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ペアの方法として保存する代わりに、反射を使用してそれに渡すべき議論として、実行する必要のある代表者を保存できます。これを行う最も簡単な方法は、タイプのリストを保存することです 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」によるソリューションは、私が説明したことを正確に行います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top