简体   繁体   English

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

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

I am quite new to C# and want to know the right way (not wasting any resources) to handle Generic Data.我对 C# 很陌生,想知道处理通用数据的正确方法(不浪费任何资源)。

I have a BindingList that is used to bind dataGridView.DataSource.我有一个用于绑定 dataGridView.DataSource 的 BindingList。

Below is the example code that updates Data values: The question is whether it be more efficient to place the "calculating codes" in the getter or the setter.下面是更新数据值的示例代码: 问题是将“计算代码”放在 getter 还是 setter 中是否更有效。

If there is an approach to this that would be considered a 'best practice' please let me know that too.如果有一种方法可以被认为是“最佳实践”,请也告诉我。

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

... where the Data class is used like so: ...其中数据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();
    }
}

Q: "The question is whether to place "calculating codes" to the getter or not."问:“问题是是否将“计算代码”放在 getter 中。

A: Short answer: Do the calculation once in the set instead of on every get .答:简短回答:在set中计算一次,而不是在每次get时计算。

Long answer:长答案:

I notice your 'Code' property is a string but the underlying value seems to be a float .我注意到您的“代码”属性是一个字符串,但基础值似乎是一个float That's ok, but I have a few suggestions for optimizing:没关系,但我有一些优化建议:

  1. Obviously, the input string value in the 'Code' property setter will have to be parsed at some point in order to perform the float calculation shown in your code.显然,必须在某些时候解析“代码”属性设置器中的输入字符串才能执行代码中显示的浮点计算。 The float.Parse() method will throw a hard Exception as written here. float.Parse() 方法将抛出一个硬异常,如此处所述。 Make sure you add some validation code to the input string and fail gracefully if it can't be parsed.确保向输入字符串添加一些验证代码,如果无法解析,则正常失败。
  2. To fire the PropertyChanged event, I suggest the form here: use the nameof keyword and make OnPropertyChanged protected virtual so that inherited classes can fire the event, too.要触发 PropertyChanged 事件,我建议这里的表单:使用nameof关键字并使 OnPropertyChanged 受保护虚拟,以便继承的类也可以触发该事件。

  3. It's just an opinion of course, but I would do the calculation once in the setter, not the getter.当然,这只是一种意见,但我会在 setter 中进行一次计算,而不是在 getter 中。 But then if it's stored as a float, I would do the ToString() in the getter.但是,如果它存储为浮点数,我会在 getter 中执行 ToString() 。

  4. I don't see the harm in a short-running calculation in the setter.我没有看到 setter 中的短期计算有什么害处。 If it's some kind of long-running task to perform a calculation, consider using a method instead and possibly doing it asynchronously as a Task.如果执行计算是某种长时间运行的任务,请考虑改用方法,并可能将其作为任务异步执行。


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

Since a lot of this has to do with 'style points' there are other perspectives than my own.由于这其中很多都与“风格点”有关,因此还有其他观点而不是我自己的观点。 I do believe there's enough substance to justify posting this answer and hope it provides some insights for the thing you are asking.我确实相信有足够的内容来证明发布此答案的合理性,并希望它为您所问的事情提供一些见解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM