Array.Clear实际上做了什么?

时间:2011-04-05 19:46:44

标签: c# .net exception clr cil

我正在寻找答案来解决Array.Clear(...)方法在C#中的功能。

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

我之所以这样问,是因为我对Array.Clear的调用偶尔会引发SEHException,我似乎无法弄清楚它为什么会发生。

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

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

  

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

2 个答案:

答案 0 :(得分:6)

设想 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互操作调用。

答案 1 :(得分: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);
}

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