Faire de cette méthode de réflexion appel typesafe
-
01-10-2019 - |
Question
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 suivi des changements sur ce message entrant, pour exécuter les modifications sur un autre objet. Procédé pour l'exécution est transmis à PropertyChanged sous forme de chaîne. Quelqu'un at-il une astuce comment je peux faire ce coffre-fort de type?
La solution
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);
}
}
}
Autres conseils
Vous voulez éviter de passer le nom de la méthode comme une chaîne? Pourquoi ne pas faire 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);
}
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 Action
délégué générique 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:. On dirait que je suis plus lent avec l'écriture du code, mais je vais garder ce ici une explication - la solution par « DTB » fait exactement ce que je décrivais