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 .没关系,但我有一些优化建议:
- 显然,'Code' 属性 setter 中的输入字符串 value 必须在某个时候进行解析才能执行您的代码中显示的浮点数计算。 float.Parse() 方法 将抛出硬异常 ,如此处所写。确保向输入字符串添加一些验证代码,如果无法解析则优雅地失败。
要触发 PropertyChanged 事件,我建议在此处使用以下形式:使用 nameof 关键字并使 OnPropertyChanged 受保护虚拟,以便继承 类 可以也触发事件。
当然这只是一个意见,但我会在setter而不是getter中计算一次。但是如果它存储为浮点数,我会在 getter.
中执行 ToString()
我没有看到 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' 有关,所以除了我自己的观点之外还有其他观点。我确实相信有足够的内容来证明发布此答案是合理的,并希望它能为您提出的问题提供一些见解。
我是 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 .没关系,但我有一些优化建议:
- 显然,'Code' 属性 setter 中的输入字符串 value 必须在某个时候进行解析才能执行您的代码中显示的浮点数计算。 float.Parse() 方法 将抛出硬异常 ,如此处所写。确保向输入字符串添加一些验证代码,如果无法解析则优雅地失败。
要触发 PropertyChanged 事件,我建议在此处使用以下形式:使用 nameof 关键字并使 OnPropertyChanged 受保护虚拟,以便继承 类 可以也触发事件。
当然这只是一个意见,但我会在setter而不是getter中计算一次。但是如果它存储为浮点数,我会在 getter.
中执行 ToString()
我没有看到 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' 有关,所以除了我自己的观点之外还有其他观点。我确实相信有足够的内容来证明发布此答案是合理的,并希望它能为您提出的问题提供一些见解。