C#浏览列表<;结构>;韩元';不能改变值

C#浏览列表<;结构>;韩元';不能改变值,c#,foreach,addressing,C#,Foreach,Addressing,我有一个保存条件信息的结构 private struct hintStructure { public string id; public float value; public bool alreadyWarned; } private List<hintStructure> hints; 私有结构hintStructure { 公共字符串id; 公众浮动价值; 公共领域已经被警告过; } 私有列表提示; 每当我的程序更改一个值时,就会发送一个事件

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

private struct hintStructure
{
    public string id;
    public float  value;
    public bool   alreadyWarned;
}
private List<hintStructure> hints;
私有结构hintStructure
{
公共字符串id;
公众浮动价值;
公共领域已经被警告过;
}
私有列表提示;
每当我的程序更改一个值时,就会发送一个事件,并检查条件列表中的元素是否满足条件

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();
}
public void EventListener(字符串id)
{
CheckHints(id);//更新元素的id
}
私有无效检查提示(字符串\u id)
{
foreach(提示中的hintStructure)
if(_h.id==_id)校验值(_h);
}
私有无效校验值(hintStructure\u h)
{
float _f=GetValue(_h.id);
如果(\u f<\u h.值)
{
激活点(_h);
_h、 alreadyWarned=true;
}
其他的
_h、 预先警告=错误;
}
私人无效激活中心(hintStructure\u h)
{
如果(_h.alreadyWarned==false)
ShowPopup();
}
ShowPopup()
只应在该特定元素尚未显示时调用(由
bool-alreadyWarned
指示)。问题是:它总是显示出来。这似乎是一行
\u h.alreadyWarned=true,但没有存储该值(我检查了它是否被调用,是否被调用)。
我认为,
foreach
可能是问题所在(因为几年前它还存在bug),但它也不适用于
for()
结构

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

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


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

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

经典的解决方案是通过引用(
ref
)传递此实例,但不能使用
foreach
变量

解决方案是将
hintStructure
更改为class:

private class Hint
{
    public string id;
    public float  value;
    public bool   alreadyWarned;
}

问题不在于foreach本身,而在于您对可变结构的使用。不要那样做。除此之外,当您没有显示出可能导致问题的循环时,很难看到出了什么问题。请包含一个,然后停止使用可变结构…C++!C#。换句话说,在您真正理解差异并需要改进性能之前,您通常不应该在C#中使用
struct
。@PhillipH:嗯,我们怀疑是这样的。但是我们看不到代码,这就更难确定了。(不可否认,
CheckValue
中肯定存在这个问题。)但我非常确定的是,如果你避免可变结构(和公共字段!),那么就很难进入这种情况。我还强烈建议你也开始遵循.NET命名约定……这归结为:可变结构是邪恶的