Как изменить значения в словаре C++ CLI

Я пытаюсь изменить значение структуры, которая хранится как значение в 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, а для соответствующего элемента в constituentDictionary — нет. Мне непонятно, почему в словаре нет доступа к флагу value->actv.

Вы используете структуру значений, которая использует семантику копирования при записи. Вы изменяете копию структуры, хранящейся в словаре.

Mark Benningfield 13.12.2022 15:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что ваши элементы Dictionary взяты из структуры значений, которая является типом значения, а не ссылочным типом.
Вы можете увидеть более общую информацию здесь: В чем разница между ссылочным типом и типом значения в c#?.

Когда вы получаете значение от Dictionary с помощью этой строки:

trgt = constituent[comp];

Фактически вы получаете копию значения, хранящегося в Dictionary, и модифицируете эту копию.

Вы можете решить ее двумя способами:

  1. Если вы можете изменить 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;
}
  1. Если вы не можете изменить 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 было изменено.

Другие вопросы по теме

Похожие вопросы