当顶层命名空间包含基类而内部命名空间包含子类时的 C# 命名空间和类/子类命名约定

Posted

技术标签:

【中文标题】当顶层命名空间包含基类而内部命名空间包含子类时的 C# 命名空间和类/子类命名约定【英文标题】:The C# namespace and class/sub-class naming conventions when the top namespace contains the base class and inner namespaces contain sub-classes 【发布时间】:2010-11-21 00:55:51 【问题描述】:

我正在尝试为特定的工程应用程序设计一个类库,并且我正在尝试确保我的类和命名空间命名约定有意义。

我有以下情况:

namespace Vehicle

    class Wheel... //base class for Wheel objects
    class Engine... //base class for Engine objects
    ...
    namespace Truck 
        class Wheel: Vehicle.Wheel... //Truck specific Wheel object
        class Engine: Vehicle.Engine... //Truck specific Engine object
        ...
    

    namespace Car 
        class Wheel: Vehicle.Wheel... //Car specific Wheel object
        class Engine: Vehicle.Engine... //Car specific Engine object
        ...
    
    ...

代码的使用方式是所有这些类都需要在同一范围内引用。可能会出现以下情况:

...
Vehicle.Wheel.DoSomething();
Vehicle.Truck.Wheel.DoSomething();
Vehicle.Car.Wheel.DoSomething();
...

在这种情况下,我最好给类指定更具体的名称

namespace Car
    class CarWheel: Vehicle.Wheel... //Car specific Wheel object
    ...

还是保留第一个示例中所示的命名并依赖于命名空间中编码的信息以清楚起见?在后一种方法下,我假设我想在使用这个库的代码中使用 alaising 来清晰,对吗?

这似乎是多余的:

Vehicle.Car.CarWheel

Vehicle.Truck.TruckEngine

但我也希望有非常描述性和具体的类名。

从哲学上讲,我要问的是,在考虑类名是否足够具有描述性时,是否将命名空间作为类名的一部分。

【问题讨论】:

【参考方案1】:

通常命名空间是复数的,以免与类名冲突(例如,您可能想要名为 VehicleCar 的类),所以我倾向于使用如下命名空间:

namespace Vehicles;
namespace Vehicles.Cars;
namespace Vehicles.Trucks;

至于类的名称,通常会在类名前加上特化前缀,尤其是当它们可能一起使用时,所以你最终会得到类似的东西:

class CarWheel : Wheel
class TruckWheel : Wheel

您可以在 .NET Framework 的任何地方看到这种类型的“冗余”,例如在 System.Xml 命名空间中,几乎所有类都以 Xml 为前缀,或者在 System.Data.SqlClient 命名空间中,大多数类都以 @ 为前缀987654328@。这意味着您可以使用 using 指令导入命名空间,然后不必在整个代码中完全限定类名,例如以下哪个更易读?

Vehicles.Cars.Wheel wheel = new Vehicles.Cars.Wheel();

CarWheel wheel = new CarWheel();

两者都在做什么很明显,但第二个要短得多。


请注意,如果您确实在名称中包含了专业化,那么您可能会发现您不需要所有嵌套的命名空间(.Cars.Trucks 等),如果通常使用它们会变得很痛苦在一起,因此使用它们的每个文件都必须导入所有命名空间,例如

using Vehicles;
using Vehicles.Cars;
using Vehicles.Trucks;
using Vehicles.SomethingElse;
using Vehicles.YetAnotherThing;

如果您发现相同的 using 指令堆栈位于每个文件的顶部,则将这些类折叠到单个命名空间中。您通常会将预期在单个命名空间中一起使用的所有相关功能包括在内,并且仅将嵌套的功能用于扩展基本命名空间但不经常使用的功能。

【讨论】:

“典型的复数命名空间”对我帮助很大——谢谢!【参考方案2】:

我会尝试避免在不同的命名空间中重复使用名称,特别是如果客户可能希望在同一个程序中同时使用这两个名称。

您真的需要CarTruck 等的命名空间吗?所有这些命名空间听起来更像是,而不是命名空间。也许在你的实际情况下它更有意义......

【讨论】:

是的,我明白你的意思。我认为我实际遇到的情况有点不同,但我所从事的领域的术语如果没有大量背景知识将很难理解。在我的例子中,命名空间作为命名空间而不是类是有意义的。

以上是关于当顶层命名空间包含基类而内部命名空间包含子类时的 C# 命名空间和类/子类命名约定的主要内容,如果未能解决你的问题,请参考以下文章

在不同的命名空间中定义基类和派生类时的编译错误

PHP使用命名空间:别名/导入(Aliasing/Importing)

程序集...内部和外部命名空间

C# 常用 命名空间都有哪些 这些命名空间是的作用是?

命名空间和程序集

使用命名空间路由时的路由错误