16

我们知道这System.Array是一个抽象类,无论DataType[]我们使用什么运行时,都会以某种方式为我们创建一些具体的实现(虽然含糊不清)。

考虑以下代码段。

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

collection.Clear()throws NotSupportedException,这没什么好奇怪的。当我查看“StackTrace”时,惊讶地发现它SZArrayHelper在调用堆栈顶部显示了一些奇怪的“Type”。

堆栈跟踪:

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

这怎么可能?我正在调用Clear()方法,int[]但是调用如何进行SZArrayHelper.Clear。请注意,这Clear是一个实例方法,SZArrayHelper定义如下。

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

谁创建了“SZArrayHelper”的实例,并注意 Clear 方法是私有的。我对正在发生的事情感到非常困惑。如果完全创建并Clear调用了“SZArrayHelper”的实例,那么执行此调用的辅助方法应该出现在“StackTrace”中。但这里不是这样。

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

笔记:

  1. int[]只是一个例子,你几乎可以用任何类型的数组来模拟它,而且不仅ClearmethodAddContains具有相同的行为。

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

  3. Google 将我引向了这个.NET 数组、IList、通用算法,那么 STL 呢?. 这有助于了解幕后发生的那种魔法,但仍然存在一些谜团。

4

1 回答 1

9

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

collection.Clear从这个角度来看,直接调用是有道理的SZArrayHelper.Clear

Hans Passant 在这里很好地解释了这一点:https ://stackoverflow.com/a/11164210/857807

于 2013-11-11T20:12:39.770 回答