【问题标题】:C# : Why is First namespace redundant?C#:为什么第一个命名空间是多余的?
【发布时间】:2015-09-02 01:04:15
【问题描述】:

这有点吓人。

我想一定有某个地方可以解释为什么会发生这种情况。

在我们的解决方案中,大约有 50 个不同的项目。大多数情况下,这些库以命名空间 OurCompany 开头。

我们有 OurComany.This.That 和 OurCompany.Foo.Bar... 等。

外部库与命名空间之间存在命名空间/类冲突

OurCompany.Foo.Bar

还有一个像这样合格的班级..

OurCompany.Some.Location.Foo

错误是这样的:

Error   75  The type or namespace name 'MethodName' does not exist in the
namespace 'OurCompany.Foo' (are you missing an assembly reference?)

当我完全限定“OurCompany”命名空间下的任何内容时,即使 Resharper 也会给我一个“限定符是多余的”消息......即

OurCompany.Some.Location.Foo.MethodName();
//OurCompany is redundant

我无法弄清楚到底是什么在这样做。解决方案非常庞大,因此将问题拆分并尝试对问题进行逆向工程对我来说并不是一个很好的解决方案。

我应该声明,如果我使用...

Some.Location.Foo.MethodName(); //Leaving out OurCompany

...Resharper 消息消失。

【问题讨论】:

  • SomeStaticClass.SomeStaticMethod(); 有效吗?导致错误消息的代码是什么?
  • 如果你在课堂上OurCompany。你不必限定它。只需输入SomeStaticClass.SomeStaticMethod(); 甚至SomeStaticMethod(); 。这取决于你在哪里。这就是 resharper 说的原因
  • 整个解决方案都在发生这种情况。我有 3122 个错误。没有任何效果,因为它不会编译。
  • 冗余警告不是错误。您有 3122 个错误我相信您需要将一些文件引用到您的项目中才能工作。
  • 不,很抱歉,这绝对不是。在我使用命名空间“Foo”添加我的外部库之前,一切都编译得很好。由于与“Foo”命名空间的冲突,编译器对在主解决方案中使用“Foo”类的任何东西都发疯了。这很疯狂,因为 Foo 不在同一个范围内。我唯一需要做的是第一个命名空间“OurCompany”,在整个解决方案中被认为是多余的。

标签: c# namespaces projects-and-solutions qualifiers


【解决方案1】:

我以为我明白这里发生了什么,但现在我看到了一些奇怪的行为,这让我质疑我对 C# 的命名空间作用域行为的理解。

显然,基本问题是范围界定。据推测,您正在OurCompany 下的某个命名空间中处理某些东西;我们只是说为了争论,你在OurCompany.This.That。自动地,任何直接在 OurCompany.This.ThatOurCompany.ThisOurCompany 命名空间中找到的类型或命名空间都在范围内,无需使用。这就是为什么一旦涉及带有 OurCompany.Foo 命名空间的程序集(OurCompany 中的所有内容默认情况下都在范围内,包括 Foo 命名空间和命名空间 [显然] 优先),事情就会崩溃,也是为什么你重新收到冗余命名空间警告(Some 命名空间在 OurCompany 命名空间中定义,因此它自动在范围内)。

但试图重现这种行为,我遇到了一些奇怪的事情。我创建了一个文件来保存相关世界的其余部分:

namespace OurCompany
{
    namespace Some
    {
        namespace Location
        {
            public class Foo
            {
                public static void MethodName() { }
            }
        }
    }

    namespace Foo
    {
        namespace Bar { }
    }
}

发现以下(我收集到的与您正在做的类似)不起作用:

using OurCompany.Some.Location;

namespace OurCompany
{
    namespace This
    {
        namespace That
        {
            class BeepBoop
            {
                private void DoSomething()
                {
                    Foo.MethodName();  // No good; Foo is a namespace here.
                }
            }
        }
    }
}

...但是这样做了:

namespace OurCompany
{
    namespace This
    {
        namespace That
        {
            using OurCompany.Some.Location;
            class BeepBoop
            {
                private void DoSomething()
                {
                    Foo.MethodName();  // Puh-wha?  This works?
                }
            }
        }
    }
}

我坦率地承认我不知道这里发生了什么。但显然,范围并不像“范围内的任何内容都在范围内,并且命名空间优先”那么简单。

【讨论】:

  • 哇...不错的实验。
  • 看了你的回答后找到了这个链接:stackoverflow.com/questions/125319/…
  • 好的,微妙之处在于,与我最初将范围界定为基本上只是添加或删除内容的一大堆概念不同,它更加分层。所以在第一个示例中,当编译器查找Foo 时,它首先检查DoSomething。它在那里找不到它,所以它向上移动一层到 BeepBoop,依此类推,直到它到达 OurCompany 命名空间范围。在那里,它找到了一个名为 Foo 的命名空间。但在第二个示例中,一旦编译器到达 That 命名空间的作用域,它就会找到将 Foo 类带入作用域的 using 语句。
【解决方案2】:

每当我引用的 dll 未构建时,我都会看到此错误。引用可能未构建并且存在一些构建错误。因此,Resharper 和 VS 都在抱怨缺少的类型。

为了修复它,我建议您执行以下操作:

  1. 在 50 个项目的解决方案中尝试找出基础项目。您可以使用项目构建顺序(在解决方案资源管理器中右键单击 sln)
  2. 禁用所有其他项目并点击构建。
  3. 现在验证构建是否成功。如果构建不成功,请修复错误。如果成功,从步骤 1 开始重复。

我知道这很乏味,但我认为这是修复您看到的大量 (#3000) 错误的好方法。

【讨论】:

  • 感谢您的帮助。我很欣赏我的问题经过深思熟虑的阅读。
  • 祝你好运。如果您发现任何问题,请告诉我。
  • 如果确实可以解决您的问题,请将其标记为答案。
  • 请阅读 Ben Nesson 的回答。他能够证明问题的原因。看到之后,我找到了一个类似的问题,发现是命名空间解析的顺序导致了我的问题。之后,这很容易解决。
猜你喜欢
  • 2019-05-12
  • 2021-06-27
  • 2015-12-07
  • 2011-03-20
  • 2020-10-28
  • 1970-01-01
  • 2011-09-13
  • 2016-01-27
  • 2010-11-15
相关资源
最近更新 更多