Hacer esta reflexión llamada al método typesafe
-
01-10-2019 - |
Pregunta
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
});
}
}
Como se puede ver que estoy seguimiento de los cambios en este mensaje entrante, para ejecutar los cambios en otro objeto. El método de ejecución se pasa a PropertyChanged como una cadena. ¿Alguien tiene un consejo de cómo puedo hacer este tipo de seguro?
Solución
Algo como esto?
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);
}
}
}
Otros consejos
Así que usted quiere evitar pasar el nombre del método como una cadena? Por qué no conseguir el objeto MethodBase en la incubadora?
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);
}
En lugar de almacenar la "operación que hay que hacer más" como un par de método y un argumento que debe ser transmitida a él mediante la reflexión, puede almacenar un delegado que se debe ejecutar. La forma más sencilla de hacer esto es para almacenar una lista de tipo List<Action<Customer>>
- a continuación, en el método ApplyChanges
, puede iterar sobre la lista y ejecutar todas las acciones.
En caso de que no está utilizando .NET 3.5 y C # 3.0 (que define un genérico Action
delegado y apoya las expresiones lambda), todavía puede escribir esto 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:. Parece como si estuviera más lento con la escritura del código, pero voy a mantener esto aquí como una explicación - la solución 'DTB' hace exactamente lo que he descrito