2010-06-28 4 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 
      }); 
    } 
} 

Comme vous pouvez le voir, je suis le suivi des modifications sur ce message entrant, pour exécuter les modifications sur un autre objet. La méthode à exécuter est transmise à PropertyChanged en tant que chaîne. Est-ce que quelqu'un a une astuce comment je peux faire ce type de coffre-fort?Effectuez cette méthode de réflexion callafe safe

Répondre

2

Quelque chose comme ça?

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

Oui! Merci beaucoup :) – moe

1

Au lieu de stocker la « opération qui doit être fait » comme une paire de méthode et un argument qui devrait être transmis à l'aide de la réflexion, vous pouvez stocker un délégué qui doit être exécuté. La façon la plus simple de le faire est de stocker une liste de type List<Action<Customer>> - puis dans la méthode ApplyChanges, vous pouvez parcourir la liste et exécuter toutes les actions.

Dans le cas où vous ne l'utilisez .NET 3.5 et C# 3.0 (qui définit un délégué générique Action et supporte les expressions lambda), vous pouvez toujours écrire cela en 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"); }); 

EDIT: Il On dirait que j'ai été plus lent avec l'écriture du code, mais je vais garder ceci ici comme une explication - la solution par 'dtb' fait exactement ce que j'ai décrit.

+0

J'aime cette solution :-) – dtb

1

Alors vous voulez éviter de passer le nom de la méthode sous forme de chaîne? Pourquoi ne pas récupérer l'objet MethodBase dans le setter?

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