Почему $ReturnValue1 генерируется, когда я передаю (по значению) словарь<char, stack<int>> в функцию

Мы создаем игру Towers of Hanoi в окне консоли. Мы должны использовать Dictionary> для хранения игровых фигур. Я объявил его вне main как глобальный. Когда я звоню в static void function drawboard(Dictionary<char, Stack<int>>. Что бы я ни пытался, имя локальной переменной System.Collections.Generic.Dictionary<TKey, TValue>.this[TKey].get returned. Когда я смотрю переменную, она отображается как $ReturnValue1 и перезаписывает мой исходный словарь. Что происходит и как это остановить или, по крайней мере, обойти это.

Я пытался создавать клоны словаря и передавать их через чертежную доску, но он все равно переопределяет оригинал. Я попытался изменить область словаря и добавить в словарь модификаторы, такие как защищенный, частный и т. д. Я также перепрыгнул через несколько обручей и сделал свою чертежную доску немного сложнее, чем сейчас пытается обойти эту проблему. Я могу упростить это достаточно легко, если я могу понять корень моей проблемы.

--декларация--

 static Dictionary<char, Stack<int>> towers = new Dictionary<char, Stack<int>>();
            towers.Add('A', new Stack<int> { });
            for (int x = 4; x > 0; x--)
            {
                towers['A'].Push(x);
            } 
            towers.Add('B', new Stack<int> { }); 
            towers.Add('C', new Stack<int> { });

---функция тяговой доски---

static void printboard(Dictionary<char, Stack<int>> t)
    { 
        Stack<int> A = t['A'];
        Stack<int> B = t['B'];
        Stack<int> C = t['C'];


        for (int y = 0; y < 5; y++)
        {
            if (y == 4)
            {
                Console.Write("----------\n" +
                              "A   B   C\n");
            }
            else
            {
                if (A.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(A.Pop() + "   ");
                }
                if (B.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(B.Pop() + "   ");
                }
                if (C.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(C.Pop() + "   ");
                }
                Console.Write("\n");
            }
        }
    }

Предполагается, что код передает словарь по значению, извлекает значения из локальной копии словаря и выводит их в окно консоли, не затрагивая исходный словарь Towers.

Возможный дубликат Передача объектов по ссылке или значению в C#

Kelvin Lai 28.05.2019 03:31

Здесь вы передаете ссылку, которая, без сомнения, при модификации изменит значения. Что нужно сделать, так это создать глубокую копию и выполнить над ней манипуляции.

Rakshith Murukannappa 28.05.2019 06:45

Но я думал, что вам нужно использовать модификатор ref или модификатор out. Как я передал его по ссылке?

Steven Schoor 28.05.2019 07:14

@StevenSchoor, можете ли вы поделиться кодом, в котором вы вызываете функцию drawboard?

akg179 28.05.2019 07:44

печатная доска (башни); drawboard было именем ошибки, которое я сделал в почте. во всем коде его имя — printboard.

Steven Schoor 28.05.2019 08:01
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Создайте переменную типа Dictionary и назначьте ей копию исходного словаря towers, а затем передайте эту новую переменную вашему методу printboard. Что-то вроде этого:

var copiedTowers = new Dictionary<char, Stack<int>>(towers);
printboard(copiedTowers);

Это также может быть реализовано как:

printboard(new Dictionary<char, Stack<int>>(towers));

Кроме того, в методе printboard при инициализации переменной Stack<int> A используйте тот же подход для копирования содержимого значения словаря. Так:

Stack<int> A = new Stack<int>(t['A']);
Stack<int> B = new Stack<int>(t['B']);
Stack<int> C = new Stack<int>(t['C']);

Я уже пробовал это, я думаю, но ваша реализация немного отличается, поэтому я попробую это очень быстро.

Steven Schoor 28.05.2019 08:20

Нет, он все еще каким-то образом ссылается на исходный словарь и возвращается к нему.

Steven Schoor 28.05.2019 08:22

возвращает откуда?

akg179 28.05.2019 08:23

Как я уже сказал в ОП, я точно не знаю, как это делается, поскольку функция печати начинает использовать данные из моего словаря любым способом, она изменяет исходный словарь. локальные переменные появляются, когда я начинаю пытаться копировать данные в какой-либо другой стек, массив, словарь и т. д., называемый iSystem.Collections.Generic.Dictionary<TKey, TValue>.this[TKey].get return. когда я добавляю переменную Watch, эта переменная отображается как $ReturnValue1

Steven Schoor 28.05.2019 08:26

не могли бы вы поделиться кодом метода printboard в посте?

akg179 28.05.2019 08:27

добавил его в OP, но я не думаю, что он использует что-то сложное. Первоначально он просто использовал аргумент t. Передача стеков в t в локальные стеки была неудачной попыткой решить проблему.

Steven Schoor 28.05.2019 08:32

@StevenSchoor отредактировал мой ответ. Попробуйте таким же образом инициализировать локальные переменные Stack<int> в методе printboard.

akg179 28.05.2019 08:56

Спасибо, последнее редактирование сработало. Поэтому я неправильно инициализировал новые стеки. Урок выучен

Steven Schoor 28.05.2019 09:02

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