Как удалить массив в С#?
Извините, если это очевидный вопрос, но ни Google, ни поиск не привели меня к ответу.
Есть ли способ полностью удалить массив?
Я хочу противоположность int[] array = new int[5]
Ответы
Ответ 1
Скажите, что вы звоните:
void Foo(){
int[] a = new int[5];
}
В С# нет возможности определить переменную a
. Это означает, что a
будет определено в Foo
, даже если вы установите для параметра a
значение null.
Однако в конце Foo
a
выйдет за рамки. Это означает, что никакой код не может ссылаться на него, и сборщик мусора позаботится о том, чтобы освободить память для вас в следующий раз, когда она будет работать, что может быть недолго.
Ответ 2
Вы просто должны позволить ему выйти из сферы действия и ждать, пока GC его обнаружит; который может быть не сразу (на самом деле его почти наверняка не будет). Если у вас есть поле на долгоживущем объекте (оно останется в области видимости), вы можете установить значение null, что может помочь.
Вы можете влиять на GC, чтобы собирать раньше (а не только ваш объект: все подходящее), но вы редко должны , если когда-либо делать это. Я использую его только в испытательных установках; но:
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); // DON'T DO THIS!!!
для более на GC.Collect
:
Ответ 3
Нет необходимости удалять массив, GC будет иметь дело с ним.
(Очень) Упрощенно:
Когда у вас закончится память, сборщик мусора запустит, остановит ваш код и проведет все живые объекты в памяти.
live означает некоторую ссылку на стек, регистр, статическую ссылку и некоторые другие вещи, известные совместно как "GC Roots". Когда он проходит их, он отмечает, что они живы.
Если ваш массив больше не живет, нет никакого способа получить доступ к нему (это то, что определяет жизнеспособность), поэтому память, которую он занимает, будет доступна для повторного использования.
Возможно, есть причина, по которой ссылка ссылается на null, если она будет содержать ссылки дольше, чем это требуется, или она требует большой объем памяти, который вам нужен немедленно, но это может легко отразиться и на самом деле заставить массив жить дольше. Переменные экземпляра, а не стека, являются лучшими кандидатами для этой оптимизации, если содержательный экземпляр будет иметь значительно больший срок службы, чем содержащий его массив.
Чтобы быть ясным, как новичок вы не должны обдумывать подобные вещи, пусть GC сделает это и попытается помочь, когда вы:
- знать, что вам нужно
- знать, как
- знать, как проверить, что вы сделали это правильно.
Ответ 4
Вы должны прочитать статью Криса Брумме по этому вопросу; первые несколько абзацев должны объяснить ситуацию.
И любой, предлагающий "присваивать значение null переменной", должен обратить особое внимание на часть, которая гласит:
Даже если вы добавите "aC = null;" после вашего использования JIT может считать это назначение мертвым кодом и устранить его.
Ответ 5
Удалить? Установите его в значение null:
array = null;
Ответ 6
array = null, но я думаю, что будет хорошей идеей, если вы немного почитаете модель управления памятью .NET, чтобы полностью понять, почему.
Ответ 7
Просто пояснить, если вы не понимаете какую-либо терминологию, выраженную в других ответах, GC означает сборщик мусора. Языки, такие как С#, которые имеют автоматическое управление памятью, позволяют сосредоточиться на том, что нужно сделать, а не беспокоиться о том, что вы создаете и когда его удалять. GC работает, периодически просматривая все созданные вами объекты и видя, есть ли у них какие-либо ссылки на них. Если нет, это означает, что вы не можете ничего с ними сделать, поэтому их также можно удалить, и система делает именно это.
Подробнее см. http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
Ответ 8
Ближе всего вы можете просто ждать, пока он выйдет из области видимости или установит нулевое значение.
Он не удалит или не удалит массив сразу, но после того, как вы поместите все ссылки на массив, сборщик мусора (GC) удалит его вовремя...
Ответ 9
Вы можете объявить и инициализировать свой массив в выражении if (true) {}, из оператора if (после него) переменная массива недоступна, поэтому она будет удалена.
Ответ 10
В С++ можно использовать ключевое слово delete. И он был первоначально упомянут в этом комментарии и в других комментариях. История изменений показывает это. Это жизнеспособный (хотя и побочный ответ), даже если другие не понимают, почему. Я говорю это, потому что можно использовать его, чтобы найти свое изящное решение, если они понимают более одного языка.
В .NET/MSIL у вас есть ключевое слово delete, но оно называется variablename.Dispose(). Я предлагаю это, потому что он удаляет все ссылки на переменную и подталкивает ее к состоянию готовности к сборке мусора. Другой вариант - установить переменную равную null, так как это сохранит переменную как типизированный объект, но отпустите то, что она удерживает в сборке мусора, чтобы впоследствии ее можно было переназначить.
Оригинальный комментарий/ответ:
Коллекция мусора для С# отличная и все, но иногда вам действительно нужно удалить переменную из памяти и создать новый экземпляр, без какой-либо другой части вашей программы, поддерживающей ее. У одного есть возможность потенциально разместить существующий кусок памяти, хранящийся в массиве, в состояние GC, указав массив на новый кусок памяти, например:
aMyArray = new int[];
Основная проблема, которую я вижу таким образом, однако, заключается в том, что вы действительно не хотите тратить массу памяти, а затем все заканчивается, когда GC запускается, потому что ОС запутана. Я придерживаюсь этой мысли, учитывая, что C Sharp теперь является основным языком и используется в LOT различных приложений, в том числе в написании игр... Было бы здорово, если бы C Sharp не действовал подобно ActionScript/FLASH в этом уважение.
Ответ 11
В С++ существует ключевое слово delete
для удаления всего, что вы хотите из памяти. Конечно, вы можете с ним также удалить массивы, поэтому вы можете написать функцию в С++, которая принимает массив как параметр, а в реализации вы просто добавляете одну строку кода, которая немедленно удаляет ее. Если эта функция принадлежит классу в проекте библиотеки классов, то вы можете добавить ссылку в С#, создать экземпляр с использованием пространства имен и вызвать функцию или не создавать экземпляр, если функция была объявлена статической.
Если тип проекта в С++ не был библиотекой классов, а просто файлом dll, тогда вы должны экспортировать объявленную функцию (extern "C" __declspec (dllexport), а в С# использовать ее с помощью System.Runtime.InteropServices.DllImport
. Когда вы используете dll import, важно указать строку пути к файлу dll и после добавления вызова Convention = CallingConvention
. Cdecl, если вы не хотите получать исключения и проблемы каждый раз, когда вы вызываете импортированную функцию.
Вы можете прочитать в Интернете, как это сделать. Надеюсь, это хорошая идея.
Пример кода:
Проект dll С++:
extern "C" __declspec( dllexport ) void Delete(array<__int32>^ arr)
{
delete arr;
}
Проект С#:
using System;
using System.Runtime.InteropServices;
namespace DeleteArray
{
class Program
{
[DllImport("...DeleteArray.dll", Convention=CallingConvention)]
static extern void Delete(int[] arr);
static int Main(string[] args)
{
int[] array = new int[] { 1, 2, 3, 4, 5 };
foreach (int integer in array)
{
Console.WriteLine(integer);
}
Delete(array);
Console.Write(array[0]); //Runtime error!
return 0;
}
}
}
Я пробовал это дома, и он отлично работал у меня, так почему бы и другим!?
Ответ 12
Возможно, это было решено, но вы можете рассматривать массив как стек. Прокрутите его и вытащите верхнюю часть каждой итерации.
while(true)
{
if(array.Length==0)
{
break;
}
array.Pop();
}
таким образом вы можете просто нажимать больше значений в массив без необходимости повторного его создания