Тайна за System.Array

Мы знаем, что System.Array является абстрактным классом, и независимо от того, DataType[], который мы используем, во время выполнения создает для нас какую-то конкретную реализацию (хотя и расплывчато).

Рассмотрим следующий фрагмент.

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

collection.Clear() бросает NotSupportedException, Ничего удивительного там нет. Когда я проверяю "StackTrace", я удивляюсь, когда на вершине стека вызовов отображается какой-то странный "Type" SZArrayHelper.

StackTrace:

   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". Но это не тот случай.

Может кто-нибудь объяснить, что происходит за кулисами?

Примечание:

  1. int[] является лишь примером, вы можете в значительной степени смоделировать его с любым типом массива, и не только метод Clear Add, Contains и т.д. Имеет такое же поведение.

  2. Я попытался отладить с помощью отражателя аддин, который дал мне те же результаты. Отладчик показывает прямой вызов SZArrayHelper.Clear<T>().

  3. Google привел меня к этим .NET-массивам, IList, общим алгоритмам, а как насчет STL?. Это помогло понять, какая магия происходит за кулисами, но некоторая загадка все еще остается.

Ответ 1

Вы не видите никакого вызова этого метода, потому что вы вызываете его сами, как это ни странно, как это может звучать. SZArrayHelper - это оболочка CLR вокруг массива, которая реализует интерфейс IList<T>, как и шаблон адаптера.

С этой точки зрения имеет смысл, что collection.Clear вызывает SZArrayHelper.Clear напрямую.

Hans Passant здесь очень хорошо объясняет: fooobar.com/info/11613/...