Мы создаем игру 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.
Здесь вы передаете ссылку, которая, без сомнения, при модификации изменит значения. Что нужно сделать, так это создать глубокую копию и выполнить над ней манипуляции.
Но я думал, что вам нужно использовать модификатор ref или модификатор out. Как я передал его по ссылке?
@StevenSchoor, можете ли вы поделиться кодом, в котором вы вызываете функцию drawboard
?
печатная доска (башни); drawboard было именем ошибки, которое я сделал в почте. во всем коде его имя — printboard.
Создайте переменную типа 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']);
Я уже пробовал это, я думаю, но ваша реализация немного отличается, поэтому я попробую это очень быстро.
Нет, он все еще каким-то образом ссылается на исходный словарь и возвращается к нему.
возвращает откуда?
Как я уже сказал в ОП, я точно не знаю, как это делается, поскольку функция печати начинает использовать данные из моего словаря любым способом, она изменяет исходный словарь. локальные переменные появляются, когда я начинаю пытаться копировать данные в какой-либо другой стек, массив, словарь и т. д., называемый iSystem.Collections.Generic.Dictionary<TKey, TValue>.this[TKey].get return. когда я добавляю переменную Watch, эта переменная отображается как $ReturnValue1
не могли бы вы поделиться кодом метода printboard
в посте?
добавил его в OP, но я не думаю, что он использует что-то сложное. Первоначально он просто использовал аргумент t. Передача стеков в t в локальные стеки была неудачной попыткой решить проблему.
@StevenSchoor отредактировал мой ответ. Попробуйте таким же образом инициализировать локальные переменные Stack<int>
в методе printboard
.
Спасибо, последнее редактирование сработало. Поэтому я неправильно инициализировал новые стеки. Урок выучен
Возможный дубликат Передача объектов по ссылке или значению в C#