【问题标题】:How to name C# source files for generic classes如何为泛型类命名 C# 源文件
【发布时间】:2011-03-07 16:42:52
【问题描述】:

我正在尝试坚持通用命名约定,例如Design Guidelines for Developing Class Libraries 中描述的那些约定。我将每种类型放入其自己的源文件中(部分类将被拆分为多个文件,如问题Naming Conventions for Partial Class Files 中所述),使用类型的名称作为文件名。

例子:

namespace Demo.Bla                         //  project
{
    enum FlowDirection { }                 //  in file FlowDirection.cs
    class LayoutManager { }                //  in file LayoutManager.cs
}

namespace Demo.Bla.LayoutControllers       //  folder LayoutControllers in project
{
    class StackPanelLayoutController { }   //  in file LayoutControllers/StackPanelLayoutController
}

但我不确定我是否想出了一个聪明的方法来命名包含泛型类的源文件。例如,假设我有以下课程:

namespace Demo.Bla.Collections             //  folder Collections
{
    class Map<T> { }                       //  in file Map.cs (obviously)
    class Bag { }                          //  in file Bag.cs (obviously)
    class Bag<T> : Bag { }                 //  also in file Bag.cs ???
}

我是否应该将非泛型和泛型Bag 类的代码放入同一个Bag.cs 文件中?你的习惯是什么?

【问题讨论】:

标签: c# naming-conventions


【解决方案1】:

我认为这个问题的常见解决方案是这样命名文件:

{ClassName}`{NumberOfGenericParameters}

这会给你这个文件名:

Bag.cs and Bag`1.cs

这是 Microsoft 在 Asp.net Mvc 等框架中处理此问题的方式。

【讨论】:

  • 哦,我没有意识到反引号是文件名中的合法字符(至少在 Windows 上)。所以这意味着任何泛型类型的名称中都应该有一个反引号和一个数字。嗯,我得好好想想。谢谢。
  • @Pierre,是的。这就是我解决问题的方法。但是,当我只有泛型类而没有非泛型版本时,我通常不会将反引号字符放在文件名中。因此,在您的情况下,我会将通用 Map 类放在名为“Map.cs”的文件中。
  • 我在MVC框架中找不到示例,所以想知道是否仍然普遍这样做。但它是在实体框架中完成的,这里有一个例子:entityframework.codeplex.com/SourceControl/latest#src/…`.cs
【解决方案2】:

我见过一些库使用

Bag.cs
Bag`1.cs
Bag`2.cs

因为这是Type.Name 将显示的内容。

我希望类型参数更具描述性,所以我最近倾向于使用

Bag.cs
Bag{T}.cs
Bag{TKey, TValue}.cs

XML cmets 也支持这种格式。

/// <summary>
/// ...
/// Uses the <see cref="T:MyLibrary.Bag{TKey, TValue}" /> class.
/// </summary>

【讨论】:

  • der welten - 感谢您的建议。我喜欢将类型参数直接放入文件名的想法,而不是较短的反引号 + 数字命名方案。
  • 我也喜欢他们将类型参数放在文件名中的方式,但在 dotnet/corefx 指南中,他们建议使用 Type`{num}.cs, :(
【解决方案3】:

通常,如果我有几种类型被类型参数的数量“重载”,那是因为一种类型是从另一种派生的,或者一种用于创建另一种。我只是将它们放在同一个文件中。

另一种选择是将它们拆分为不同的文件,根据您在问题中链接到的部分类问题,使一个文件成为“主要”文件,而其他文件在构建文件中“依赖”它。

这样您最终可以在 Visual Studio 中获得一个可视链接,但每个文件仍然有一个类,以便更轻松地使用它们。

【讨论】:

    【解决方案4】:

    CoreFX GitHub 存储库中,Microsoft 遵循Matthias Jakobsson 的回答中描述的back-tick 约定

    所以基本上:

    class ImmutableArray { }                      // ImmutableArray.cs
    class ImmutableArray<T> { }                   // ImmutableArray`1.cs
    ...
    class ImmutableDictionary<TKey, TValue> { }   // ImmutableDictionary`2.cs
    

    对于在其他类中定义的类,名称由外部类后跟+和内部类的名称(Outer+Inner.cs)组成:

    partial class ImmutableArray<T>               // ImmutableArray`1+Builder.cs
    {
        class Builder { }
    }
    

    【讨论】:

    • 我知道这已经有一年了,但我想指出,您提供的 CoreFX 链接中不再使用这种命名方法。他们现在使用下划线而不是勾号和句点而不是加号。所以“ImmutableArray`1+Builder.cs”现在将是“ImmutableArray_1.Builder.cs”
    【解决方案5】:

    我为我的泛型类的名称添加了后缀“T”。

    class Bag { }                           // in file Bag.cs 
    class BagT<T> : Bag { }                 // in file BagT.cs
    class BagInputs : BagT<Input>           // in file BagInputs.cs
    

    你问过,

    我应该将非泛型和泛型 Bag 类的代码都放在同一个 Bag.cs​​ 文件中吗?你有什么习惯?

    我的上述约定是非标准的;我应该澄清一下,我回答的是“我的习惯是什么”,而不一定是“你应该做什么”。

    【讨论】:

    • 这在我看来有点不寻常。如果您在 .NET 4 中设计 Tuple 类型,您会怎么做?
    • @Jon - 是的,不寻常:我使用了一些非标准的命名约定,不一定很像 .NET 库类型的命名约定。我以前没有遇到过那些Tuple 类型,但我想我会在同一个TupleT.cs 中将它们全部称为TupleT
    • 有趣;谢谢你的想法,但我不太喜欢它。它不适合 .NET 中使用的所有其他泛型类型(List&lt;int&gt; 会变成 ListT&lt;int&gt;,这让我感觉很尴尬)。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多