Reputation: 4571
I was writing this piece of C# code:
static void Main()
{
List<string> matches = new List<string>();
var result = Regex.Matches(myString, @"\((.*?)\)");
foreach(var x in result)
matches.Add(x.Groups[1].Value.ToString());
}
and I was surprised to see it fail with this error message:
Type 'object' does not contain a definition for 'Groups' and no extension method 'Groups' of type 'object' could be found.
However, this works:
foreach(Match x in result)
matches.Add(x.Groups[1].Value.ToString());
The Matches()
method returns a MatchCollection
, shouldn't it be clear that x
is a Match
?
Upvotes: 2
Views: 987
Reputation: 659994
shouldn't it be clear that x is a Match?
Sadly no.
MatchCollection
implements IEnumerable
, the non-generic legacy interface. It does not implement IEnumerable<Match>
. So no, that is not clear.
Because the foreach
loop was designed in an era before generics, it automatically inserts a cast to the loop variable type. That is
foreach(Match x in result)
matches.Add(x.Groups[1].Value.ToString());
is the moral equivalent of
IEnumerator enumtor = result.GetEnumerator();
while (enumtor.MoveNext())
{
Match x = (Match)(enumtor.Current);
...
You could have said
foreach(Giraffe x in result)
and it would have compiled just fine, and died at runtime.
When you say
foreach(var x in result)
The compiler sees that there is no type information to infer beyond object, so that's what it gives you for the type of x. Your error then follows from there.
I do not know why the collection has not been updated to make it more amenable to static typing; you'd have to ask the BCL team.
Upvotes: 11