繁体   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