Array.Clear实际上做了什么?

Aro*_* W. 7 .net c# clr cil exception

我正在寻找答案,该Array.Clear(...)方法在C#的封面下做了什么.

我已经查看了IL,但这并没有真正产生任何线索,因为它只是调用System.Array::Clear(...)mscorlib中的方法,然后调用CLR的一个我无法观察到的非托管部分.

我问这个的原因是,我偶尔会因为调用Array.Clear而引发SEHException,而我似乎无法弄清楚它为什么会发生.

不幸的是,微软似乎对抛出异常时可能意味着什么有点守口如瓶......

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

默认情况下,任何未自动映射到特定异常的SEH异常都会映射到SEHException类.有关更多信息,请在MSDN Library中搜索"非托管异常"和"结构化异常处理".

Jar*_*Par 6

设想 Array.Clear这样写是最容易的

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

我意识到Array.Clear实际上并不是一个通用的方法,我试图展示一个关于幕后发生的事情的密切映射.真的,虽然它更接近

memcopy(&array, 0, array.Length * sizeof(T));
Run Code Online (Sandbox Code Playgroud)

如果此代码抛出,SEHException则最可能的原因是源阵列周围的内存已损坏.最可能的来源是错误的PInvoke或COM互操作调用.


Han*_*ant 5

您可以在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);
}
Run Code Online (Sandbox Code Playgroud)

换句话说,它只是将0个字节压缩到元素中.获得SEHException的唯一方法是通过处理器故障.GC堆损坏.查看任何pinvoke或COM互操作代码.