C#var关键字混淆:类型'对象'不包含...错误的定义

Eut*_*rpy 2 c# var type-inference

我正在编写这段C#代码:

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());
    }
Run Code Online (Sandbox Code Playgroud)

我很惊讶地看到它失败并显示以下错误消息:

"对象"类型不包含"组"的定义,也没有找到"对象"类型的扩展方法"组".

但是,这有效:

foreach(Match x in result)
    matches.Add(x.Groups[1].Value.ToString());
Run Code Online (Sandbox Code Playgroud)

Matches()方法返回一个MatchCollection,不应该很清楚x是一个Match

Eri*_*ert 11

不应该很清楚x是匹配吗?

可悲的是没有.

MatchCollection实现IEnumerable,非通用遗留接口.它没有实现IEnumerable<Match>.所以不,那不清楚.

因为foreach循环是在泛型之前的时代设计的,所以它会自动将强制转换插入到循环变量类型中.那是

foreach(Match x in result)
  matches.Add(x.Groups[1].Value.ToString());
Run Code Online (Sandbox Code Playgroud)

是道德等同于

IEnumerator enumtor = result.GetEnumerator();
while (enumtor.MoveNext())
{
    Match x = (Match)(enumtor.Current);
    ...
Run Code Online (Sandbox Code Playgroud)

你可以说

foreach(Giraffe x in result)
Run Code Online (Sandbox Code Playgroud)

它会编译得很好,并在运行时死亡.

当你说

foreach(var x in result)
Run Code Online (Sandbox Code Playgroud)

编译器发现没有类型信息可以推断超出对象,因此它为x的类型提供了它.然后你的错误从那里开始.

我不知道为什么集合没有更新,以使其更适合静态类型; 你必须问BCL团队.

  • @Eutherpy - 你可以使用[`Cast <Match>()`]显式地将`IEnumerable`转换为`IEnumerable <Match>`(https://msdn.microsoft.com/library/bb341406(v = vs.100)的.aspx).这将让你保持你的`var`. (3认同)