Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When enumerating a MatchCollection, why does var result in Object type rather than Match type?

Tags:

c#

regex

I noticed something that seems odd in the following code:

MatchCollection mc = Regex.Matches(myString, myPattern);
foreach(var match in mc)
    Console.WriteLine(match.Captures[0]); // <-- this line is invalid, unless I replace 'var' above with 'Match'

The variable match is of type Object rather than Match. I am used to enumerating collections using var with no issues like this. Why is MatchCollection different?

like image 578
D'Arcy Rittich Avatar asked Jul 26 '11 14:07

D'Arcy Rittich


2 Answers

MatchCollection was written before .NET 2, so it just implements IEnumerable rather than IEnumerable<T>. However, you can use Cast to fix this very easily:

foreach(var match in mc.Cast<Match>())

If you give the variable an explicit type, like this:

foreach(Match match in mc)

... then the C# compiler inserts a cast on each item for you automatically. This was required in C# 1 to avoid having casts all over your code.

(Logically even with var there's a conversion involved - but it's always from one type to the same type, so nothing actually needs to be emitted.) See section 8.8.4 of the C# 4 spec for more details.

like image 193
Jon Skeet Avatar answered Nov 11 '22 19:11

Jon Skeet


Try this:

foreach(Match match in mc)

Since MatchCollection does not implement IEnumerable<T> the enumerator in the foreach will receive an object for each Match in the sequence. It is your job to cast the object to the right type.

So when you use var in the foreach loop you are implicitly typing match to object since that is what is being yielded by the enumerator. By explicitly typing match to Match you are instructing the compiler to cast each match to the right type on your behalf.

like image 23
Andrew Hare Avatar answered Nov 11 '22 18:11

Andrew Hare