为什么编译器与继承中的名称空间冲突

时间:2019-05-21 14:25:54

标签: c# inheritance compiler-errors

在以下代码中

namespace Too
{
    public class Foo
    {

    }
}

namespace Foo
{

    public class Boo : Foo
    {

    }
}

我收到错误'foo' is a namespace but is used like a type。 如果我将继承中的Foo类名完全限定为Too.Foo,该错误就会消失。

为什么编译器会尝试在名称空间没有意义的地方尝试解析Foo名称空间而不是类?

3 个答案:

答案 0 :(得分:4)

当编译器首次解析名称时,它并不关心您的引用是类还是名称空间。如果名称不完全合格,它将始终尝试首先在本地名称空间中找到它-包括名称空间名称本身。如果无法在本地名称空间中找到它,它将尝试使用using指令。

之所以这样解决,是因为您毕竟可以创建一个名称空间层次结构,并且所有类和名称空间都由.分隔。因此,在解析名称时,编译器并不在乎类型,而仅在乎层次结构路径。一旦找到匹配项,它就会关心类型。在这种情况下,当它需要一个类并因此失败时,它是一个命名空间。

对于子命名空间和子类,如果编译器仅尝试匹配一个子命名空间和子类,则很难识别匹配项;如果仅匹配同一程序集中的随机命名空间,则编译器可能会找到多个引用。因此,它始终始终是本地名称空间,然后在层次结构中向上移动到其他程序集。如果由于两个被引用的不同名称空间中存在两个具有相同名称的子名称空间或类而导致不清楚,则您必须更加清楚。

答案 1 :(得分:0)

因为Foo在另一个名称空间中。继承Foo时

namespace Foo 
{

    class Boo: Foo {

您未指定要引用的Foo。是Foo名称空间还是Too.Foo

答案 2 :(得分:0)

在您试图继承新类的class Foo中,编译器找不到namespace Foo。您必须完全限定该名称,这不是您不能跳过或不做的事情,除非:

namespace Foo
{
    using Too;

    public class Boo : Foo // now is ok, compiler will look into `Too` too
    {
    }
}

没有using或完全合格的名称编译器甚至没有查看namespace Too。尝试使用任何类型,例如List<T>,而没有完全指定它,或者在方法中没有using System.Collections.Generic,同样的问题,您会得到错误

  

找不到类型或名称空间名称'Foo'(您是否缺少using指令或程序集引用?)


至于错误:

  

CS0118'Foo'是一个命名空间,但其使用方式类似于类型

之所以会这样,是因为编译器位于范围内(如果我可以这么说的话)Foo,该范围恰好是一个名称空间,您不应该将其用作基本类型。


@RenéVogt更好地提出了这个问题:

  

为什么编译器不能以一种可行的方式实现

要获得答案,我们必须询问开发人员。但是以我的理解,这不会是一个巨大的收获,并且值得为此而付出努力。我个人认为告诉编译器在哪里查看没有问题。

考虑这种情况:

namespace Foo
{
    public class Foo { }
    public class Boo : Foo { }
    public class BooToo : Foo { } // here I want Too.Foo, how?
}

即使编译器调查namespace Too,您仍然会有冲突。