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?

¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top