2010-06-28 47 views
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。有沒有人有提示我如何使這種類型安全?使此反射方法調用類型安全

回答

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

是的!非常感謝:) – moe 2010-06-28 16:27:01

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'的解決方案完全符合我所描述的內容。

+0

我喜歡這個解決方案:-) – dtb 2010-06-28 16:02:42

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