我们知道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()
这怎么可能呢? 我在int[]
上调用Clear()
方法,但是调用如何转到SZArrayHelper.Clear
. 请注意,Clear
是实例方法,SZArrayHelper
定义如下。
private void Clear<T>()
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
}
谁创建了"SZArrayHelper"的实例,并注意清除方法是私有的。我对正在发生的事情感到非常困惑。如果创建了"SZArrayHelper"的实例并调用了Clear
则执行此调用的帮助程序方法应该位于"StackTrace"中。但这里的情况并非如此。
有人可以解释一下幕后发生的事情吗?
注意:
int[]
只是一个例子,你几乎可以用任何类型的数组来模拟它,不仅Clear
方法Add
、Contains
等都具有相同的行为。
我尝试使用反射器插件进行调试,这给了我相同的结果。调试器显示对
SZArrayHelper.Clear<T>()
的直接调用。Google将我带到了这个.NET Arrays,IList,Generic Algorithms,以及STL呢?这有助于理解幕后发生的那种魔力,但仍然存在一些谜团。
您没有看到对该方法的任何调用,因为您自己调用它,尽管这听起来很奇怪。 SZArrayHelper
是围绕数组的 CLR 包装器,它实现IList<T>
接口,有点像适配器模式。
从这个角度来看,collection.Clear
直接调用SZArrayHelper.Clear
是有道理的。
Hans Passant在这里很好地解释了这一点:https://stackoverflow.com/a/11164210/857807