System.Array背后的谜团

时间:2013-11-11 19:44:13

标签: c# .net

我们知道System.Array是一个抽象类,无论DataType[]我们使用运行时为我们创建了一些具体的实现(虽然模糊不清)。

请考虑以下代码段。

int[] someInts = { 1, 2, 3, 4 };
IList<int> collection = someInts;
collection.Clear();

collection.Clear()抛出NotSupportedException,没有什么值得惊讶的。当我查看“StackTrace”时,我惊讶地看到它在调用堆栈顶部显示了一些奇怪的“类型”SZArrayHelper

堆栈跟踪:

   at System.SZArrayHelper.Clear[T]()//Note this.. How???
   at TestApplication.Program.Main()

怎么可能?我在Clear()上调用了int[]方法,但调用如何转到SZArrayHelper.Clear。请注意ClearSZArrayHelper中的实例方法,定义如下。

private void Clear<T>()
{
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
}

谁创建了“SZArrayHelper”的实例,还注意到Clear方法是私有。我很困惑地看到发生了什么。如果创建了一个“SZArrayHelper”实例并且调用了Clear那么执行此调用的辅助方法应该出现在“StackTrace”中。但这不是这种情况。

有人可以解释幕后发生的事情吗?

注意:

  1. int[]只是一个例子,你几乎可以用任何类型的数组来模拟它。不仅Clear方法AddContains等拥有相同的行为..

  2. 我尝试使用反射器插件调试,这给出了相同的结果调试器显示直接调用SZArrayHelper.Clear<T>()

  3. 只是谷歌引导我进入.NET Arrays, IList, Generic Algorithms, and what about STL?。这有助于理解某种魔法落后但神秘仍然存在。

1 个答案:

答案 0 :(得分:7)

你没有看到任何对该方法的调用,因为你自己调用它,就像听起来一样奇怪。 SZArrayHelper是一个围绕数组的CLR包装器,它实现了IList<T>接口,有点像适配器模式。

从这个角度来看,collection.Clear直接调用SZArrayHelper.Clear是有意义的。

Hans Passant在这里解释得非常好:https://stackoverflow.com/a/11164210/857807