#c# #struct
#c# #структура
Вопрос:
Итак, я пытаюсь создать небольшую змеиную игру на C # и консоли и столкнулся с каким-то странным поведением. Я всегда думал, что структуры должны передаваться как значения, а не ссылки. Но теперь, когда я пытаюсь скопировать структуру во временный буфер, а затем нарисовать ее, по какой-то причине она присоединяется к буферу в качестве ссылки:/ Когда я изменяю drawBuffer . карта также изменяется. и я не хочу, чтобы карта была изменена.
map — это статическое значение, установленное над функцией
Map drawBuffer = new Func<Map>(() => map)(); //trying to forcibly pass the value through a function as an attempt to separate it from the refrence.
MovePlayer();
foreach ((int x, int y) in player.Tail)
{
drawBuffer[x, y, 1] = 'O';
}
а карта — это структура.
struct Map //also tried to make it immutable via readonly; nothing.
{
public const char EMPTY = (char)0;
public int Width;
public int Height;
public int Depth;
char[,,] container;
public char this[int x, int y, int z]
{
get
{
return container[x, y, z];
}
set
{
container[x, y, z] = value;
}
}
public char this[int x, int y]
{
get
{
for (int z = Depth - 1; z >= 0; z--)
{
if (container[x, y, z] != EMPTY)
{
return container[x, y, z];
}
}
return EMPTY;
}
}
public void DrawSurface()...
public void DrawLayer(int z)...
public Map(int width, int height, int depth)
{
this.Width = width;
this.Height = height;
this.Depth = depth;
container = new char[width, height, depth];
}
public Map(int width, int height, int depth, Func<int, int, int, int, int, int, char> pattern)
{
this.Width = width;
this.Height = height;
this.Depth = depth;
container = new char[width, height, depth];
for (int x = 0; x < width; x )
{
for (int y = 0; y < height; y )
{
for (int z = 0; z < depth; z )
{
this[x, y, z] = pattern(x, y, z, width, height, depth);
}
}
}
}
}
Комментарии:
1. «скопируйте структуру во временный буфер, а затем нарисуйте ее, по какой-то причине она прикрепляется к буферу в качестве ссылки» — не могли бы вы уточнить, пожалуйста? Где вы копируете ? Что вы копируете? Куда он прикрепляется? Что означает прикрепить себя в качестве ссылки? Как вы полагаете, что есть проблема?
2. хм, я думаю, это немного неясно. прикрепление, как при изменении буфера рисования. карта также будет изменена. я хочу скопировать map в drawBuffer, чтобы я мог временно изменить drawbuffer, не затрагивая карту. @Sinatr
3.
char[,,] container;
является ссылочным типом. Не имеет значения, что он находится внутри astruct
, копияstruct
означает, что оба имеют ссылки на один и тот жеcontainer
массив4. есть ли альтернатива, которая позволила бы избежать этой проблемы?
Ответ №1:
Как упоминалось UnholySheep char[,,] container
, это ссылочный тип. Чтобы избежать передачи его в качестве ссылки, вы могли бы создать новую карту и передать значение напрямую следующим образом:
Map secondMap;
for (int z = 0; z < drawBuffer.container.GetLength(2); z )
for (int y = 0; y < drawBuffer.container.GetLength(1); y )
for (int x = 0; x < drawBuffer.container.GetLength(0); x )
secondMap.container[x, y, z] = drawBuffer.container[x, y, z];
Комментарии:
1. Я решил использовать clone, если мне это снова где-нибудь понадобится, хотя я не знал, что смогу получить длину по размеру, так что это будет полезно!
container = (char[,,])toClone.container.Clone();
2. Вы также можете ответить на свой вопрос тем, что вы включили в свой комментарий @jklw10, чтобы другим было легче найти решение
Ответ №2:
Вместо того, чтобы вручную копировать значения из одного места в другое, я использую встроенную функцию Clone() в конструкторе, которая принимает карту.
public Map(Map toClone)
{
Width = toClone.Width;
Height = toClone.Height;
Depth = toClone.Depth;
container = (char[,,])toClone.container.Clone();
}
таким образом, он выглядит довольно чистым в коде.
Map drawBuffer = new Map(map);
вы также можете реализовать пользовательскую функцию клонирования
public Map Clone(Map toClone){
Map newMap = new map(toClone.Width, toClone.Height, toClone.Depth)
newMap.container = (char[,,])toClone.container.Clone();
return newMap;
}