Как foreach может узнать тип элемента двумерного массива, если он не реализует IEnumerable?C#

Место общения программистов C#
Ответить
Anonymous
 Как foreach может узнать тип элемента двумерного массива, если он не реализует IEnumerable?

Сообщение Anonymous »

Кажется, я не могу согласовать эти два наблюдения:
  • 2D-массив () нельзя назначить переменной типа IEnumerable
  • In foreach(var item in (T[,])array2d), компилятор знает, что var — это T.
Я думал, что foreach — это просто синтаксический сахар, который использует IEnumerable.GetEnumerator() (в этом случае var — это T) или IEnumerable.GetEnumerator() (в этом случае var — это объект).
Вот сценарий, который привел меня к этому вопросу. У меня есть метод, который принимает IEnumerable.

Код: Выделить всё

int Average(IEnumerable values)
{
// lots of code
foreach (var foo in values)
{
var bar = foo.GetBar();
// lots of code
}
// lots of code
return result;
}

Foo[] array1d = /**/;
Average(array1d);
Затем я хотел передать этому методу двумерный массив, но он не компилируется; ошибка: CS1503. Аргумент 1: невозможно преобразовать из «Foo[*,*]» в «System.Collections.Generic.IEnumerable».

Код: Выделить всё

Foo[,] array2d = /**/;
Average(array2d);
Однако я обнаружил, что он компилируется, если я просто добавляю эту перегрузку. Когда я нахожу курсор мыши на var foo, компилятор знает, что это Foo, и может найти Foo.GetBar().

Код: Выделить всё

void Average(Foo[,] values)
{
// lots of code
foreach (var foo in values)
{
var bar = foo.GetBar();
// lots of code
}
// lots of code
return result;
}
К сожалению, это дублирует мой код. В качестве альтернативы я мог бы вызвать Average(array2d.Cast());, но это добавляет дополнительный итератор, а мне нужна производительность. Итератор, вероятно, не окажет существенного влияния на производительность, но кажется, что должен быть лучший способ.

Подробнее здесь: https://stackoverflow.com/questions/790 ... lement-ien
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»