C# 在通用数据中使用 getter 和 setter 更新数据的正确方法(数据:INotifyPropertyChanged)

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

我是 C# 的新手,想知道处理通用数据的正确方法(不浪费任何资源)。

我有一个 BindingList 用于绑定 dataGridView.DataSource。

下面是更新数据值的示例代码:问题是将 "calculating codes" 放在 getter 或 setter.[=14= 中是否更有效]

如果有一种方法可以被认为是 'best practice',请也告诉我。

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

... Data 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();
    }
}

问:"The question is whether to place "计算代码"是否为getter。"

A:简答:在 set 中计算一次,而不是在每个 get.

中计算一次

长答案:

我注意到你的 'Code' 属性 是 string 但基础值似乎是 float .没关系,但我有一些优化建议:

  1. 显然,'Code' 属性 setter 中的输入字符串 value 必须在某个时候进行解析才能执行您的代码中显示的浮点数计算。 float.Parse() 方法 将抛出硬异常 ,如此处所写。确保向输入字符串添加一些验证代码,如果无法解析则优雅地失败。
  2. 要触发 PropertyChanged 事件,我建议在此处使用以下形式:使用 nameof 关键字并使 OnPropertyChanged 受保护虚拟,以便继承 类 可以也触发事件。

  3. 当然这只是一个意见,但我会在setter而不是getter中计算一次。但是如果它存储为浮点数,我会在 getter.

  4. 中执行 ToString()
  5. 我没有看到 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);
    }

由于很多内容都与 'style points' 有关,所以除了我自己的观点之外还有其他观点。我确实相信有足够的内容来证明发布此答案是合理的,并希望它能为您提出的问题提供一些见解。