簡體   English   中英

C# 在通用數據中使用 getter 和 setter 更新數據的正確方法(數據:INotifyPropertyChanged)

[英]C# Right way to update Data using getter and setter in Generic Data (Data : INotifyPropertyChanged)

我對 C# 很陌生,想知道處理通用數據的正確方法(不浪費任何資源)。

我有一個用於綁定 dataGridView.DataSource 的 BindingList。

下面是更新數據值的示例代碼: 問題是將“計算代碼”放在 getter 還是 setter 中是否更有效。

如果有一種方法可以被認為是“最佳實踐”,請也告訴我。

public class Data : INotifyPropertyChanged
{
    private float number;
    public string Code
    {
        get => Number; //  get => Number / 100     which one is more efficient?
        set { Number = value / 100; OnPropertyChanged(); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

...其中數據class 的使用如下:

public partial class Form1 : Form
{
    private BindingList<Data> dataList = new BindingList<Data> { new Data { Code = "1"  } };

    protected override void OnHandleCreated(EventArgs e)
    {
        // When main form is ready to handle messages the binding happens.
        base.OnHandleCreated(e);
        myDataGridView.DataSource = dataList;
        myDataGridView.Columns["Code"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    public Form1()
    {
        InitializeComponent();
    }
}

問:“問題是是否將“計算代碼”放在 getter 中。

答:簡短回答:在set中計算一次,而不是在每次get時計算。

長答案:

我注意到您的“代碼”屬性是一個字符串,但基礎值似乎是一個float 沒關系,但我有一些優化建議:

  1. 顯然,必須在某些時候解析“代碼”屬性設置器中的輸入字符串才能執行代碼中顯示的浮點計算。 float.Parse() 方法將拋出一個硬異常,如此處所述。 確保向輸入字符串添加一些驗證代碼,如果無法解析,則正常失敗。
  2. 要觸發 PropertyChanged 事件,我建議這里的表單:使用nameof關鍵字並使 OnPropertyChanged 受保護虛擬,以便繼承的類也可以觸發該事件。

  3. 當然,這只是一種意見,但我會在 setter 中進行一次計算,而不是在 getter 中。 但是,如果它存儲為浮點數,我會在 getter 中執行 ToString() 。

  4. 我沒有看到 setter 中的短期計算有什么害處。 如果執行計算是某種長時間運行的任務,請考慮改用方法,並可能將其作為任務異步執行。


    public string Code
    {
        get => _number.ToString(); // 'Some' inefficiency here, but probably storing as float is preferred.
        set 
        {
            // I would offer that doing this ONCE in the setter
            // is more efficient than calculating on every get.
            float floatValue = float.Parse(value);  // Warning: Will throw exception 
                                                    // is value if unparsable input string
            _number = floatValue / 100;

            // Preferred form here is to use the 'nameof' keyword
            OnPropertyChanged(new PropertyChangedEventArgs(nameof(Code)));
        }
    }
    // I suggest some other notation than 'Number' because this
    // is a private field and when you say 'Number' the expectation is 
    // a public property. I see this notation often in Google source code
    // to indicate a 'private field' and have adopted it myself:
    private float _number;

    public event PropertyChangedEventHandler PropertyChanged;

    // This is customarily 'protected virtual'
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }

由於這其中很多都與“風格點”有關,因此還有其他觀點而不是我自己的觀點。 我確實相信有足夠的內容來證明發布此答案的合理性,並希望它為您所問的事情提供一些見解。

暫無
暫無

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

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