Передается ли Queue.dequeue () в C # по ссылке или по значению? - PullRequest
0 голосов
/ 10 мая 2019

Поэтому я пытаюсь использовать Очереди для создания пула объектов, чтобы перерабатывать их. Я, кажется, все еще получаю те же уровни использования памяти после его реализации. Я изо всех сил пытаюсь понять, является ли использование queue () или dequeue () передачей по ссылке или значению.

void ClearNodeListandBackupToPool(ref List<Node> nodelist)    
{    
    foreach (var node in nodelist)    
    {    
        nodePool.Enqueue(node);    
    }

    nodelist.Clear();    
}

Node CreateNewNode(Vector2 tile, Node parent, double gCost, double hCost)    
{    
    if (nodePool.Count > 0)    
        return nodePool.Dequeue().init(tile, parent, gCost, hCost);    

    return new Node(tile,parent,gCost,hCost);    
}

Я ожидал, что использование этого метода будет низким или нулевым, но оно не изменилось. Спасибо за помощь! :)

1 Ответ

0 голосов
/ 10 мая 2019

Когда вы вызываете Dequeue, возвращается значение, являющееся ссылкой на возвращаемый объект.Прежде чем объяснить, что это значит, проще сказать, почему это, вероятно, не имеет значения для вас:

Если вы сделаете это:

var list = new List<Object>();
list.Add(new object());
var o = list[0];

Теперь есть две ссылки на один и тот же объект.list имеет одну ссылку, а o имеет другую ссылку.Если o вышел из области видимости, а list - нет, то объект не будет собирать мусор, поскольку на него все еще есть ссылка.

Если вы сделаете это:

var queue = new Queue<Object>();
queue.Enqueue(new object());
var o = queue.Dequeue();

Существует только одна ссылка на объект, который был в очереди.Зачем?Потому что, как только вы удалите его из очереди, элемент будет удален из очереди, поэтому в очереди больше нет ссылки на него.o является единственной ссылкой, и если o выходит из области видимости, объект может получить сборщик мусора, поскольку на него больше нет ссылок.

Вопрос о том, возвращается ли объект по значению илиссылка не имеет большого значения.

Что означает, что ссылка возвращается по значению?

В приведенном выше примере с использованием списка list[0] возвращает значение, которое является ссылкой на объект.Если мы сделаем это:

var list = new List<Object>();
list.Add(new object());
var o = list[0];
o = "x";

... o теперь ссылается на строку, но элемент в списке не изменился.Он не был заменен на «х».Это связано с тем, что при извлечении элемента из списка возвращается значение, копия ссылки на объект.Мы не получили реальную ссылку.Таким образом, o = "x"; заменяет копию ссылки, возвращенную из списка, а не фактическую ссылку, содержащуюся в списке.

Другие заметили - и я согласен - что гораздо проще понять поведение, чемвыразить это словами.Примеры легко следовать, но описание происходящего не так.

C # 7 введено ref returns.Это позволяет методу возвращать объект по ссылке.Это означает, что метод возвращает собственную ссылку.Это легко заметить, потому что вы будете использовать ключевое слово ref при вызове метода, например ref var object = ref queue.Dequeue().(Вы не можете сделать это, потому что Dequeue не использует ref returns.)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...