C#值的意外更改-当心调试器

时间:2019-01-10 15:26:35

标签: c# properties

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。我希望现在能够解决主要问题,否则....(这对您的业余时间构成威胁:))

2 个答案:

答案 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;