How can foreach know the item type of a 2D array when it's doesn't implement IEnumerable T ?

preview_player
Показать описание

Below, you can find the text related to the question/problem. In the video, the question will be presented first, followed by the answers. If the video moves too fast, feel free to pause and review the answers. If you need more detailed information, you can find the necessary sources and links at the bottom of this description. I hope this video has been helpful, and even if it doesn't directly solve your problem, it will guide you to the source of the solution. I'd appreciate it if you like the video and subscribe to my channel!How can foreach know the item type of a 2D array when it's doesn't implement IEnumerable T ?

I can't seem to reconcile these two observations:

A 2D array (T[,]) can't be assigned to a variable of type IEnumerable T
In foreach(var item in (T[,])array2d), the compiler knows that var is T.

A 2D array (T[,]) can't be assigned to a variable of type IEnumerable T
T[,]
IEnumerable T
In foreach(var item in (T[,])array2d), the compiler knows that var is T.
foreach(var item in (T[,])array2d)
var
T
I thought foreach was just syntactic sugar that uses IEnumerable T .GetEnumerator() (in which case var is T), or IEnumerable.GetEnumerator() (in which case var is object).
foreach
IEnumerable T .GetEnumerator()
var
T
IEnumerable.GetEnumerator()
var
object
Here is the scenario that led me to this question. I have a method that takes an IEnumerable Foo .
IEnumerable Foo
int Average(IEnumerable Foo 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);

int Average(IEnumerable Foo 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);

I then wanted to pass a 2D array to this method, but it doesn't compile; the error is CS1503 Argument 1: cannot convert from 'Foo[*,*]' to 'System.Collections.Generic.IEnumerable Foo '.
CS1503 Argument 1: cannot convert from 'Foo[*,*]' to 'System.Collections.Generic.IEnumerable Foo '
Foo[,] array2d = /**/;
Average(array2d);

Foo[,] array2d = /**/;
Average(array2d);

However, I discovered that it does compile if I just add this overload. When I mouse over var foo, the compiler knows that it is a Foo, and is able to find Foo.GetBar().
does
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;
}

void Average(Foo[,] values)
{
// lots of code
foreach (var foo in values)
{
var bar = foo.GetBar();
// lots of code
}
// lots of code
return result;
}

Unfortunately, this duplicates my code. I could alternatively call Average(array2d.Cast Foo ());, but this adds an extra iterator, and I'm looking for performance. The iterator probably won't affect performance significantly, but it feels like there has to be a better way.
Average(array2d.Cast Foo ());

Tags: c#,multidimensional-array,foreach,var,c#-12.0Source of the question:

Question and source license information:
Рекомендации по теме
join shbcf.ru