2015-08-02 2 views
0

Я объявил основной-структуру, как этотКак правильно очистить очередь, содержащую структуры?

private struct ValLine { 
    public string val; 
    public ulong linenum; 
} 

и объявил очереди, как этот

Queue<ValLine> check = new Queue<ValLine>(); 

Тогда в использовании установки StreamReader, где я читал через линии входного файла с помощью ReadLine в то время как петли, между прочим, я это делаю для заполнения очереди:

check.Enqueue(new ValLine { val = line, linenum = linenum }); 

(«строка» представляет собой строку, содержащую текст каждого line, «linenum» - это просто счетчик, который инициализируется в 0 и каждый раз увеличивается через цикл.)

Назначение очереди проверки - это то, что если конкретная строка соответствует некоторым критериям, я сохраняю это строка в поле «проверка» вместе с номером строки, который он встречает во входном файле.

После того как я закончил читать через входной файл, я использую «проверить» для различных вещей, но потом, когда я закончил использовать его очистить его очевидным образом:

check.Clear(); 

(В качестве альтернативы, в моем последнем цикле «проверка» я мог бы просто использовать .Dequeue() вместо того, чтобы его использовать.)

Но потом я подумал - подожди минутку, как насчет всех этих «новых ValLine», Я генерировал при заполнении очереди в первую очередь ??? Я создал утечку памяти? Я довольно новичок в C#, поэтому мне не ясно, как с этим справиться - или даже если с ним нужно иметь дело (возможно .Clear() или .Dequeue() автоматически обрабатывает теперь устаревшие структуры). Я провел более часа с нашим дорогим другом Google и просто не нашел конкретного обсуждения этого примера в отношении очистки коллекции.

Итак ... В C# нам нужно иметь дело с вытиранием отдельных структур перед очисткой очереди (или по мере удаления объекта) или нет? И если да, то каков правильный способ сделать это?

(Только в случае, если это необходимо, я использую .NET 4.5 в Visual Studio 2013.)

UPDATE: Это для будущей ссылки (вы знаете, как если эта страница появляется в поиске Google) в отношении правильного кодирования. Для того, чтобы сделать непреложный-структуру в соответствии с рекомендацией, это то, что я закончил с:

private struct ValLine { 
    private readonly string _val; 
    private readonly ulong _linenum; 
    public string val { get { return _val; } } 
    public ulong linenum { get { return _linenum; } } 
    public ValLine(string x, ulong n) { _val = x; _linenum = n; } 
} 

В соответствии с этим изменением, линия населения очереди теперь это:

check.Enqueue(new ValLine(line,linenum)); 

Кроме того, хотя и не строго необходимо, я избавиться от моего Еогеаспа на очереди (и check.Clear();, и изменил его на этот

while (check.Count > 0) { 
    ValLine ll = check.Dequeue(); 
    writer.WriteLine("[{0}] {1}", ll.linenum, ll.val); 
} 

так, что очередь опорожняются, как информация выводится.

ОБНОВЛЕНИЕ 2: Хорошо, да, я все еще новичок C# (менее года). Я многому учусь из Интернета, но, конечно, я часто смотрю примеры из более чем года назад.Я изменил свою-структуру, так что теперь это выглядит следующим образом:

private struct ValLine { 
    public string val { get; private set; } 
    public ulong linenum { get; private set; } 
    public ValLine(string x, ulong n): this() 
    { this.val = x; this.linenum = n; } 
} 

Интересно, что я на самом деле пытался именно это от верхней части головы перед заходом с тем, что в первом обновлении (выше), но получил ошибка компиляции (потому что у меня не было : this() с конструктором). По дальнейшему предложению я еще раз проверил и нашел недавний пример, показывающий, что : this() за то, что он работает, как я и делал раньше, подключил это, и - Wa La! - чистая компиляция. Мне нравится более чистый вид кода. То, что называются частными переменными, не имеет отношения ко мне.

ответ

1

Нет, вы не создали бы утечку памяти. Вызов Clear или Dequeue очистит память надлежащим образом - например, если у вас List<T> то четкая операция может использовать:

for (int i = 0; i < capacity; i++) 
{ 
    array[i] = default(T); 
} 

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

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

+0

Вы имеете в виду это? 'private struct ValLine { public string val {get; задавать; } общественный ulong linenum {get; задавать; } } ' –

+1

@Steve: Ну, у этого есть свойства, а не общедоступные поля, но это все еще измененная структура ... –

+0

Я должен был упомянуть, что я все еще новичок, когда дело доходит до C#. Я иду из мира C/C++ и использовал C# около 9 месяцев. Таким образом, вы видите мое использование структуры в простом C-стиле (но внутри очереди, очевидно). Я сделаю некоторое исследование того, о чем вы говорите. Я знаю, к чему относится mutable/immutable, но нюансы, как то, о чем вы говорите, вне моего опыта. (Я думал об этом только в случае использования строк или StringBuilder до сих пор.) Я немного пересмотрю это. –

Смежные вопросы