Я пытаюсь изменить значение структуры, которая хранится как значение в Dictionary<>
, но я могу изменить значение, но оно не обновляется в самом словаре:
using namespace System::Collections::Generic;
value struct amplPhse {
double ampl;
double phse;
int indx;
bool actv;
};
Dictionary<String ^, amplPhse> constituent;
bool
activate(String^ comp, bool flag) {
bool retv = false;
amplPhse ^trgt;
if (constituent.ContainsKey(comp)) {
trgt = constituent[comp];
trgt->actv = flag;
retv = true;
}
return retv;
}
// Fill Dictionary with data ... and activate a component
fillDictionary();
activate("Comp", true);
После вызова функции activate()
для trgt->actv
устанавливается значение true, а для соответствующего элемента в constituent
Dictionary
— нет. Мне непонятно, почему в словаре нет доступа к флагу value->actv
.
Проблема в том, что ваши элементы Dictionary
взяты из структуры значений, которая является типом значения, а не ссылочным типом.
Вы можете увидеть более общую информацию здесь: В чем разница между ссылочным типом и типом значения в c#?.
Когда вы получаете значение от Dictionary
с помощью этой строки:
trgt = constituent[comp];
Фактически вы получаете копию значения, хранящегося в Dictionary
, и модифицируете эту копию.
Вы можете решить ее двумя способами:
amplPhse
на ref class
, код будет вести себя так, как вы ожидаете:ref class amplPhse {
public:
amplPhse(bool a) : actv{ a } {}
bool actv;
};
int main()
{
Dictionary<String^, amplPhse^> constituent;
constituent.Add("k1", gcnew amplPhse{false});
Console::WriteLine(constituent["k1"]->actv);
amplPhse^ trgt = constituent["k1"];
trgt->actv = true;
Console::WriteLine(constituent["k1"]->actv);
return 0;
}
amplPhse
, вы можете обернуть его в тип ссылки и сохранить обертку в Dictionary
:value struct amplPhse {
bool actv;
};
ref class amplPhseWrapper
{
public:
amplPhseWrapper(amplPhse a) : ampl{ a } {}
amplPhse ampl;
};
int main()
{
Dictionary<String^, amplPhseWrapper^> constituent;
constituent.Add("k1", gcnew amplPhseWrapper{amplPhse{ false }});
Console::WriteLine(constituent["k1"]->ampl.actv);
amplPhseWrapper^ trgt = constituent["k1"];
trgt->ampl.actv = true;
Console::WriteLine(constituent["k1"]->ampl.actv);
return 0;
}
В обоих случаях вывод:
False
True
т.е. значение в Dictionary
было изменено.
Вы используете структуру значений, которая использует семантику копирования при записи. Вы изменяете копию структуры, хранящейся в словаре.