C# foreaching through list<struct> won't change values

c# foreach addressing

285 просмотра

2 ответа

76 Репутация автора

I have a struct holding condition informations.

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

Whenever my program changes a value, an event is sent and the condition list is checked wether that element meets a condition.

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() should only be called, when it wasn't already shown for that specific element (indicated by bool alreadyWarned). Problem is: It's always shown. It seems like the line _h.alreadyWarned = true; is called, but the value isn't stored (I checked if it gets called, it does). I assumed the foreach might be the problem (since it was buggy some years ago), but it doesn't work with a for() structure either.

My last guess is an addressing issue, typical problem in C++: CheckValue(h); vs. CheckValue(&h); But if I'm correct with this guess - how can I solve this?

Автор: Jonas Zimmer Источник Размещён: 04.03.2016 02:41

Ответы (2)


5 плюса

5616 Репутация автора

You are passing a struct, not a class instance. Changes to a struct (not passed as ref) are changing the local copy of the struct. You are trying to make the struct as a reference type.

Changes made to a struct within a function do not change the value of the originating struct - the struct is copied to the stack before being passed up to the function.

Автор: PhillipH Размещён: 04.03.2016 02:44

5 плюса

13975 Репутация автора

Решение

The problem is structs in C# are value type, so when you call CheckValue(_h) you are creating a copy of _h and that copy is updated, but original in the list remains intact.

The classic solution is passing this instance by reference (ref), but you can't do it with foreach variables.

The solution is change hintStructure to class:

private class Hint
{
    public string id;
    public float  value;
    public bool   alreadyWarned;
}
Автор: Arturo Menchaca Размещён: 04.03.2016 02:50
Вопросы из категории :
32x32