命名空间和具有相同名称的类?

use*_*788 85 c# namespaces class

我正在组织一个库项目,我有一个名为的中央管理器类,Scenegraph以及生活在Scenegraph命名空间中的一大堆其他类.

我真的很想对场景图是MyLib.Scenegraph和其他类为MyLib.Scenegraph.*,但似乎这样做将是使所有其他类的内部类的唯一途径Scenegraph在Scenegraph.cs文件,这只是太笨拙.

相反,我已经将它组织为,Mylib.Scenegraph.Scenegraph并且MyLib.Scenegraph.*,哪种工作,但我发现Visual Studio在某些条件下会混淆我是否指的是类或命名空间.

有没有一种很好的方法来组织这个软件包,这样对于用户来说很方便,而不会在一个难以维护的混乱中将我的所有代码组合在一起?

pin*_*man 101

我不建议你命名一个像它的命名空间一样的类,看看这个.

框架设计指南在3.4节中说明"不要对命名空间使用相同的名称,也不要在该命名空间中使用类型".那是:

namespace MyContainers.List 
{ 
    public class List { … } 
}
Run Code Online (Sandbox Code Playgroud)

为什么这么糟糕?哦,让我数一下.

你可以让自己陷入一种情况,你认为你指的是一件事,但实际上是指其他事情.假设你最终处于这种不幸的情况:你正在编写Blah.DLL并导入Foo.DLL和Bar.DLL,不幸的是,它们都有一个名为Foo的类型:

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL: 
namespace Bar { public class Foo { } }

// Blah.DLL: 
namespace Blah  
{   
using Foo;   
using Bar;   
class C { Foo foo; } 
}
Run Code Online (Sandbox Code Playgroud)

编译器出错.Foo.Foo和Bar.Foo之间的"Foo"含糊不清.游民.我想我会通过完全限定名称来解决这个问题:

   class C { Foo.Foo foo; } 
Run Code Online (Sandbox Code Playgroud)

这现在给出了模糊性错误" Foo in Foo.Foo在Foo.Foo和Bar.Foo之间是不明确的 ".我们仍然不知道第一个Foo指的是什么,直到我们能够弄明白,我们甚至懒得试图弄清楚第二个指的是什么.

  • 这是一个有趣的观点.我仍然对它嗤之以鼻.谢谢.我必须诚实地以"风格指南说"开头的论点不要让我印象深刻.我在风格指南中看到了很多不合理的废话.但是你在上面做了一个很好的实践论证.无论如何,值得思考. (6认同)
  • 以上都是再见和意见。*事实*是你不应该这样做,因为 **C# 编译器会误解它**,尽管被清楚地告知发生了什么。例如,`using Foo.Bar;` 然后是`Bar b` 很清楚地指的是`Bar`,它是命名空间`Foo.Bar` 内的一个类(或枚举)。不这样做的真正原因纯粹是 C# 编译器无法正确理解它,这非常令人惊讶和不幸。其他任何东西都是羊毛风格的建议。 (5认同)
  • 回应说"什么不该做".一些堆栈用户寻找"做什么".有人会推荐Ant_222答案吗? (3认同)
  • 如果你真的陷入困境,你仍然可以在命名空间之外创建一个类型别名.只有两个完全相同的完整标识符(名称空间+类名)时才需要外部别名. (3认同)
  • 我不明白。为什么 Foo.Foo 是模棱两可的?在这种特定情况下,您直接对编译器说您要使用命名空间 Foo 中的类 Foo。不? (2认同)
  • 这个解释没有意义。这就是在编程语言中拥有命名空间的全部目的。 (2认同)
  • 事实上,我认为这种解释并不能回答问题,因为这种歧义可能因任何其他原因发生在任何地方。这就是为什么该语言有“using Foo1 = Foo”或“global::Foo.Foo”。 (2认同)

son*_*nny 11

正如其他人所说,避免将类命名与其名称空间相同是一个好习惯。

以下是svick对 Software Engineering Stack Exchange 上的相关问题“相同的类和命名空间名称”的回答中的一些其他命名建议:

你是对的,你不应该将命名空间命名为与其包含的类型相同的名称。我认为您可以使用以下几种方法:

  • 复数:Model.DataSources.DataSource

如果命名空间的主要目的是包含从相同基类型继承或实现相同接口的类型,则这种方法尤其有效。

  • 缩短:Model.QueryStorage

如果命名空间仅包含少量类型,则也许您根本不需要该命名空间。

  • 使企业化:模型.项目系统.项目

这尤其适用于产品中重要的功能,因此它们应该有自己的名字。


GoT*_*oTo 9

给命名空间和类赋予相同的名称可能会像其他人所说的那样混淆编译器.

那怎么命名呢?

如果命名空间有多个类,则找到定义所有这些类的名称.

如果命名空间只有一个类(因此诱使它赋予它相同的名称),则命名空间ClassName NS.这就是Microsoft至少命名其命名空间的方式.

  • 我投反对票,因为这没有解决问题,而且我从未见过末尾带有“NS”的命名空间......这绝对不是它的完成方式 (3认同)
  • 您是否有Microsoft提供的此类名称空间的示例? (2认同)

Pau*_*ner 9

当它是命名空间的主类时,就会发生这种情况。因此,将命名空间放入库中的动机之一是,如果将“Lib”添加到命名空间名称中,问题就会消失......

namespace SocketLib
{
    class Socket
    {
Run Code Online (Sandbox Code Playgroud)


Dar*_*ekt 9

尽管我同意其他答案,因为您不应将类命名为与命名空间相同的名称,但有时您无法遵守此类要求。

例如,在我的情况下,我不是做出这样决定的人,因此我需要找到一种方法来让它发挥作用。

因此,对于那些无法更改命名空间名称或类名称的人来说,这里是一种使您的代码工作的方法。

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL: 
namespace Bar { public class Foo { } }

// Blah.DLL: 
namespace Blah
{
    using FooNSAlias = Foo;//alias
    using BarNSAlias = Bar;//alias
    class C { FooNSAlias.Foo foo; }//use alias to fully qualify class name
}
Run Code Online (Sandbox Code Playgroud)

基本上我创建了命名空间“别名”,这使我能够完全限定类,并且 Visual Studio 的“混淆”消失了。

注意: 如果在您的控制范围内,您应该避免这种命名冲突。仅当您无法控制相关类和命名空间时,才应使用上述技术。

  • 我投了赞成票,因为这是对不完美世界的一个有趣的解决方案。 (4认同)

Ant*_*222 8

我建议你按照我的建议microsoft.public.dotnet.languages.csharp使用MyLib.ScenegraphUtil.ScenegraphMyLib.ScenegraphUtil.*.


Mar*_*ara 6

老帖子,但我在这里提出另一个可能对某人有帮助的想法:

“...但似乎唯一的方法是在 Scenegraph.cs 文件中将所有其他类设为 Scenegraph 的内部类,这太笨拙了。”

对于许多场景来说,这确实是更好的实现。但是,我确实同意将所有代码放在同一个 .cs 文件中很烦人(至少可以这么说)。

您可以通过将基类设为“部分类”来解决这个问题,然后继续在自己的文件上创建内部类(只需记住,他们必须声明基类补充,然后继续使用特定的内部类对于该文件)。

就像是...

场景图.cs:

namespace MyLib
{
    public partial class Scenegraph
    {
        //Scenegraph specific implementations
    }
}
Run Code Online (Sandbox Code Playgroud)

DependentClass.cs:

namespace MyLib
{
    public partial class Scenegraph
    {
        public class DependentClass
        {
            //DependentClass specific implementations
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我确实认为这更接近于内部类的干净实现,而不必将所有内容弄乱在一个巨大而混乱的文件中。

  • 仅当两个类都在同一个项目中时才有效......这违背了问题的目的 (2认同)

m-y*_*m-y 5

CA1724: Type Names Should Not Match Namespaces ...

基本上,如果您按照代码分析进行正确编码,则该规则表示不执行您要执行的操作.代码分析在帮助您发现潜在问题方面非常有用.