Visual Studio 2017上的C#。
我创建了我的课程,并实例了该课程的对象。 在该类中,只有两个私有值字段,具有两个访问它们的属性和一个私有标志(布尔)。 问题是:属性的set访问器仅触摸其(仅在逻辑上)相关的字段和标志,但是在执行时,当我“调用”该属性的set访问器时,所有字段都将受到影响。
在我的实现中,我只有一个带有按钮的表单:按钮的提示按钮使用他的属性增加了第一个字段的值。
我的代码。
public class DriveMeCrazyClass
{
public double _num; // a number
public double _dou; // his double
public bool dou_isValid; // I'll really update the field value only on a request.
// The idea is:
// _num e _dou are related, so when _num changes
// I should calculate the new value for _dou.
// BUT
// I prefer to postpone the calculation
// to the moment when I will be asked for the value
// SO
// I only "take note" of this fact on the flag dou_isValid
public DriveMeCrazyClass()
{
_num = _dou = 0;
dou_isValid = true;
}
public event EventHandler DMCCchanged;
public double Num
{
get { return _num; }
set
{
if (_num == value) return;
_num = value;
dou_isValid = false;
DMCCchanged?.Invoke(this, EventArgs.Empty);
}
}
public double Dou
{
get
{
if (dou_isValid) return _dou;
dou_isValid = true;
DMCCchanged?.Invoke(this, EventArgs.Empty);
return _dou = 2 * _num;
}
set
{
// ..... no matter now
}
}
}
public partial class Form1 : Form
{
public DriveMeCrazyClass aa = new DriveMeCrazyClass();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
aa.DMCCchanged += new System.EventHandler(aa_changed);
lblNum.Text = "0";
lblDou.Text = "0";
}
private void Num_inc_Click(object sender, EventArgs e)
{
aa.Num++;
}
private void aa_changed(object sender, EventArgs e)
{
lblNum.Text = aa._num.ToString();
lblDou.Text = aa._dou.ToString();
}
}
就像编译器调用Dou属性的get访问器一样。 我不知道为什么优化?还是什么?真的,我不明白。 有人可以帮我吗?
***** EDIT ******
我输入了一个新的代码,略有更改。 _num和_dou现在是公共的,我添加了两个标签以显示其值-不使用访问器Num e Dou。
无需调试:效果很好!
但是
如果我在Num.set上设置一个断点,然后继续逐步进行-观看Num和Dou值-真是一团糟!调试器调用访问器Dou.get并更新_dou值,并将标志dou_isValid设置为true。我知道,我会处理。
好的,现在很清楚!真的,Thx Robin,Thx Camilo和Thx。
顺便说一句...这个问题是更大的一部分,涉及bindig。我希望现在能够解决主要问题,否则....(这对您的业余时间构成威胁:))
答案 0 :(得分:4)
就像编译器调用Dou属性的get访问器一样。我不知道为什么。
不是编译器,而是调试器。当您查看类的属性时,它将获取所有属性的值,并运行代码。
方法不是由调试器运行的,因此可以运行:
double GetDou()
{
if (dou_isValid) return _dou;
dou_isValid = true;
return _dou = 3 * _num;
}
答案 1 :(得分:-2)
以这种方式尝试:
dou => num*2;
在这里,dou是类似num的属性,但是当num的值时会自动设置。
Edit:我认为您应该这样做,因为这样可以节省大量的赋值操作,大量的检查和大量的代码行。如果要在分配编号之前验证编号,请在将编号分配给num
之前对其进行验证。
num = (booleanChecker) ? newNum : num;
编辑2:我意识到您正在尝试做的事情,这是我对您的问题的解决方案:
dou => (booleanChecker) ? num*2 : dou;