2

我有一个保存条件信息的结构。

private struct hintStructure
{
    public string id;
    public float  value;
    public bool   alreadyWarned;
}
private List<hintStructure> hints;

每当我的程序更改一个值时,就会发送一个事件并检查条件列表是否满足该条件。

public void EventListener (string id)
{
    CheckHints(id); //id of the updated element
}

private void CheckHints(string _id) 
{
    foreach (hintStructure _h in hints)
        if (_h.id == _id) CheckValue(_h);
}

private void CheckValue(hintStructure _h)
{
    float _f = GetValue(_h.id);

    if (_f < _h.value)
    {
        ActivateHint(_h);
        _h.alreadyWarned = true;
    }
    else 
        _h.alreadyWarned = false;
}

private void ActivateHint(hintStructure _h)
{
    if(_h.alreadyWarned == false)
        ShowPopup();
}

ShowPopup()只应在尚未为该特定元素显示时调用(由 指示bool alreadyWarned)。问题是:它总是显示出来。似乎_h.alreadyWarned = true;调用了该​​行,但未存储该值(我检查了它是否被调用,确实如此)。我认为这foreach可能是问题所在(因为几年前它有问题),但它也不适用于for()结构。

我最后的猜测是一个寻址问题,C++中的典型问题: CheckValue(h); vs. CheckValue(&h);但如果我的猜测是正确的 - 我该如何解决这个问题?

4

2 回答 2

5

问题是C#中的结构是值类型,因此当您调用时,CheckValue(_h)您正在创建副本_h并且该副本已更新,但列表中的原始结构保持不变。

经典的解决方案是通过引用 ( ref) 传递这个实例,但你不能用foreach变量来做。

解决方案是更改hintStructure为类:

private class Hint
{
    public string id;
    public float  value;
    public bool   alreadyWarned;
}
于 2016-03-04T14:50:39.220 回答
5

您正在传递一个结构,而不是一个类实例。对结构的更改(不作为 ref 传递)正在更改结构的本地副本。您正在尝试将结构作为引用类型。

在函数中对结构所做的更改不会更改原始结构的值 - 结构在传递给函数之前被复制到堆栈中。

于 2016-03-04T14:44:51.030 回答