简体   繁体   中英

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.

I have a BindingList that is used to bind dataGridView.DataSource.

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.

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:

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."

A: Short answer: Do the calculation once in the set instead of on every get .

Long answer:

I notice your 'Code' property is a string but the underlying value seems to be a 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. 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.

  3. It's just an opinion of course, but I would do the calculation once in the setter, not the getter. But then if it's stored as a float, I would do the ToString() in the getter.

  4. I don't see the harm in a short-running calculation in the 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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