Что на самом деле делает Array.Clear под одеялом? - PullRequest
7 голосов
/ 05 апреля 2011

Я ищу ответ на то, что метод Array.Clear(...) делает под прикрытием в C #.

Я смотрел на IL, но это на самом деле не дает никаких подсказок, так какпросто вызывает метод System.Array::Clear(...) в mscorlib, который затем вызывает неуправляемую часть CLR, которую я не могу наблюдать.

Причина, по которой я спрашиваю это, заключается в том, что я иногда получаю исключение SEHException, выдаваемоемой звонок в Array.Clear, и я не могу понять, почему это происходит.

К сожалению, Microsoft, похоже, немного молчит о том, что это может означать, когда выдается исключение ....

From: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.sehexception(v=VS.100).aspx

Любое исключение SEH, которое не сопоставляется автоматически с определенным исключением, по умолчанию сопоставляется с классом SEHException.Для получения дополнительной информации выполните поиск по «неуправляемым исключениям» и «Структурной обработке исключений» в библиотеке MSDN.

Ответы [ 2 ]

6 голосов
/ 05 апреля 2011

Проще всего представить Array.Clear написанным так

public static void Array.Clear<T>(T[] array) {
  for (int i = 0; i < array.Length; i++) {
    array[i] = default(T);
  }
}

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

memcopy(&array, 0, array.Length * sizeof(T));

Если этот код выдает SEHException, то наиболее вероятной причиной является повреждение памяти вокруг исходного массива.Наиболее вероятным источником является неправильный вызов взаимодействия PInvoke или COM.

5 голосов
/ 05 апреля 2011

Такой код можно увидеть в исходном коде SSCLI20.Который выглядит так со всем удаленным шумом:

FCIMPL3(void, SystemNative::ArrayClear, ArrayBase* pArrayUNSAFE, INT32 iIndex, INT32 iLength)
{
    BASEARRAYREF pArray = (BASEARRAYREF)pArrayUNSAFE;
    // error checks
    //.. 
    char* array = (char*)pArray->GetDataPtr();
    int size = pArray->GetMethodTable()->GetComponentSize();
    ZeroMemory(array + (iIndex - lb) * size, iLength * size);
}

Другими словами, он просто отправляет 0 байтов в элементы.Единственный способ получить SEHException - сбой процессора.GC куча коррупции.Просмотрите любой pinvoke или код взаимодействия COM.

...