我们知道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
。请注意Clear
是SZArrayHelper
中的实例方法,定义如下。
private void Clear<T>()
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
}
谁创建了“SZArrayHelper”的实例,还注意到Clear方法是私有。我很困惑地看到发生了什么。如果创建了一个“SZArrayHelper”实例并且调用了Clear
那么执行此调用的辅助方法应该出现在“StackTrace”中。但这不是这种情况。
有人可以解释幕后发生的事情吗?
注意:
int[]
只是一个例子,你几乎可以用任何类型的数组来模拟它。不仅Clear
方法Add
,Contains
等拥有相同的行为..
我尝试使用反射器插件调试,这给出了相同的结果调试器显示直接调用SZArrayHelper.Clear<T>()
。
只是谷歌引导我进入.NET Arrays, IList, Generic Algorithms, and what about STL?。这有助于理解某种魔法落后但神秘仍然存在。
答案 0 :(得分:7)
你没有看到任何对该方法的调用,因为你自己调用它,就像听起来一样奇怪。 SZArrayHelper
是一个围绕数组的CLR包装器,它实现了IList<T>
接口,有点像适配器模式。
从这个角度来看,collection.Clear
直接调用SZArrayHelper.Clear
是有意义的。
Hans Passant在这里解释得非常好:https://stackoverflow.com/a/11164210/857807