Единственный способ убедиться в этом - с помощью отражения, но в 90% случаев вы можете избежать затрат, используя array is T[]
. Большинство людей собираются передать правильно типизированный массив, так что это будет делать. Но вы всегда должны предоставлять код для проверки отражения, на всякий случай. Вот как выглядит мой общий пример (обратите внимание: я написал это здесь, по памяти, так что это может не скомпилироваться, но это должно дать основную идею):
class MyCollection : ICollection<T> {
void ICollection<T>.CopyTo(T[] array, int index) {
// Bounds checking, etc here.
CopyToImpl(array, index);
}
void ICollection.CopyTo(Array array, int index) {
// Bounds checking, etc here.
if (array is T[]) { // quick, avoids reflection, but only works if array is typed as exactly T[]
CopyToImpl((T[])localArray, index);
} else {
Type elementType = array.GetType().GetElementType();
if (!elementType.IsAssignableFrom(typeof(T)) && !typeof(T).IsAssignableFrom(elementType)) {
throw new Exception();
}
CopyToImpl((object[])array, index);
}
}
private void CopyToImpl(object[] array, int index) {
// array will always have a valid type by this point, and the bounds will be checked
// Handle the copying here
}
}
РЕДАКТИРОВАТЬ : Хорошо, забыл кое-что указать. Пара ответов наивно использовала то, что в этом коде читается как element.IsAssignableFrom(typeof(T))
. Вы должны также разрешить typeof(T).IsAssignableFrom(elementType)
, как это делает BCL, в случае, если разработчик знает, что все значения в этом конкретном ICollection
на самом деле имеют тип S
, полученный из T
, и передает массив типа S[]