C#如何知道如何正确修改名称空间以使其工作?

C#如何知道如何正确修改名称空间以使其工作?,c#,namespaces,C#,Namespaces,C#如何知道如何正确修改名称空间以使其工作 最近,我遇到了一个看似简单的概念,但我对正在发生的事情缺乏清晰的理解。简单的谷歌搜索并不能帮助我获得更好的图片。所以,我提出这个问题 我有一个包含两个文件的项目: File1.cs namespace A.B.C { using E.F; public class D { G g; } } namespace A.B.E.F { public class G { } } namespace

C#如何知道如何正确修改名称空间以使其工作

最近,我遇到了一个看似简单的概念,但我对正在发生的事情缺乏清晰的理解。简单的谷歌搜索并不能帮助我获得更好的图片。所以,我提出这个问题

我有一个包含两个文件的项目:

File1.cs

namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}
namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}

namespace E.F
{

}
File2.cs

namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}
namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}

namespace E.F
{

}
现在,在我的同事指出这一点之前,我从未遇到过这种情况,尽管我读过一些关于C的深入书籍,并且有很长的C工作经验。因此,这里C#解析器做了一件非常聪明的事情。他用E.F.取
文件1.cs中获取封闭名称空间(即
名称空间A.B.C
),从封闭名称空间中删除
C
,并将
e.F
添加到其余名称空间部分。最后使用A.B.E.F获取

对我来说,修改似乎一点也不微不足道。编译器现在应该知道要从
A.B.C
中删除多少个尾随名称空间(在本例中为1-即
C
),以便添加
E.F
将导致一个包含
类G
的名称空间

现在我想问的是,我对正在发生的事情的理解是否正确,我从哪里可以了解到编译器所做的这些修改

更新

如果我们获取以下文件:

File1.cs

namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}
namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}

namespace E.F
{

}
File2.cs

namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}
namespace A.B.C
{
    using E.F;

    public class D 
    {
        G g;
    }
}
namespace A.B.E.F
{
    public class G { }
}

namespace E.F
{

}
编译器仍然能够使用E.F在
中的
A.B.E.F
文件1.cs中准确定位
A.B.E.F行,而不是
E.F
。因此,编译器并不是简单地寻找注释中指出的
E.F
名称空间,而是寻找包含
类G
E.F
。如果我错了,请纠正我

更新2

指向(来自@Damien_The_unsiever)文档的评论让我想到了File1.csFile2.cs的第一个版本。从某种意义上说,它们产生的结果如下:

namespace A
{
    namespace B
    {
        namespace C
        {
            using E.F;

            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}
现在我们可以使用E.F
在名称空间链中向上移动
。命名空间
E.F
是从命名空间
A.B
开始定义的,因此以下内容是合法的:

namespace A
{
    namespace B
    {
        using E.F;

        namespace C
        {
            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}
namespace A
{
    using B.E.F;

    namespace B
    {
        namespace C
        {
            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}
虽然以下内容不合法,因为在命名空间
A
中,我们仍然不知道
E.F
命名空间:

namespace A
{
    using E.F;

    namespace B
    {
        namespace C
        {
            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}
但是,我们知道名称空间
A
中的
B.E.F
名称空间,因此以下内容是合法的:

namespace A
{
    namespace B
    {
        using E.F;

        namespace C
        {
            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}
namespace A
{
    using B.E.F;

    namespace B
    {
        namespace C
        {
            public class D
            {
                G g;
            }
        }

        namespace E
        {
            namespace F
            {
                public class G { }
            }
        }
    }
}

所以,我的猜测是,我关于C#计算名称空间的第一个假设是错误的。实际上,C#不计算名称空间,只知道每个给定名称空间中的一组名称空间。在某些情况下,某些名称空间可能有多个名称。例如,
A.B.E.F
命名空间在
A.B
命名空间内有以下名称:
A.B.E.F
B.E.F
E.F
。所有3个名称空间名称都指向同一个名称空间。我的理解正确吗?

也许在名称空间树上来回走动直到找到一个公共根时会涉及一些回溯?@UweKeim,我更惊讶的不是这样一个算法的存在,而是我没有接触到这个主题。几乎没有一本书,教程或文章,我遇到没有考虑的主题。编译器只是试图找到
E
名称空间,并在
A.B.E
中找到它。描述了所采用的算法。查看“如果前面的步骤不成功,则对于每个名称空间N,从出现名称空间_或_类型_名称的名称空间开始,继续到每个封闭名称空间(如果有)并以全局名称空间结束,将计算以下步骤,直到找到实体”第节本规范旨在精确。它试图避免留下一些其他语言最终导致的空白和堆积如山的未定义行为。