Eutherpy
Eutherpy

Reputation: 4571

C# var keyword confusion: Type 'object' does not contain a definition for... error

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

Answers (1)

Eric Lippert
Eric Lippert

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

Related Questions