簡體   English   中英

使此反射方法調用類型安全

[英]Make this reflection method call typesafe

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。 有沒有人提示我如何使這種類型的安全?

像這樣嗎

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

您可以存儲應該執行的委托,而不是將“需要完成的操作”作為一對方法和應使用反射傳遞給它的參數存儲。 最簡單的方法是存儲類型為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”的解決方案完全符合我的描述。

因此,您要避免將方法名稱作為字符串傳遞? 為什么不在設置器中獲取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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM