【问题标题】:Use of 'Common Type System' as coding standard使用“通用类型系统”作为编码标准
【发布时间】:2012-06-29 09:23:55
【问题描述】:

我们的编码标准“规则”之一是:

  • 使用通用类型系统。例如,使用Int32 而不是int

我以前从未见过类似的规则,尽管我们的其他准则大致基于 Microsoft 的 Design Guidelines DigestCommon Type System 似乎也不像。

我发现这很不方便,因为我最终不得不重写默认的 Visual Studio 和 ReSharper 重构以将 string 转换为 Stringfloat 转换为 Singlelong 转换为 Int64 等。 它的应用也相当不一致(例如,不适用于 objectObject),可能是由于其不便,并且没有 StyleCop 规则来检查它是否已应用。

因此,我想知道为什么会设置此规则。有什么好的理由吗?例如,是否有任何情况(可能是历史性的)必须使用Int32 而不是int

更新

我通读了推荐的框架设计指南(2006 年,Cwalina 和 Adams)第 3.2.3 节 避免使用特定语言的名称,他们指出“避免使用这些名称很重要特定于语言的类型名称在标识符中”(我的重点)。同意。

然而,Jeffrey Richter 继续评论“我更进一步,从不使用该语言的别名,[因为它] 没有增加任何价值,并引入了巨大的混乱”。 也许这就是这条规则的由来?

【问题讨论】:

  • 可能有 c/c++ 可移植背景的人偏执?
  • 很少有不能使用通用类型系统的情况。一个例子:你有没有try to inherit an enum from System.Int16 instead of byte
  • 如果这是确切的措辞,那么写它的人就会感到困惑。在 C# 中,intSystem.Int32确切同义词,因此也是“通用类型系统”的一部分。现在,如果他们写的是“使用类型的本地名称而不是 C# 同义词”,他们至少会是准确的(尽管仍然被误导,IMO)
  • 如果规则不方便,请更改它。事实上,我在我们的编码标准中写了相反的内容:)
  • 我们的编码标准要求对变量使用别名类型名称,例如stringint 并使用 C# 同义词进行静态成员访问,例如Int32.MaxValueString.Format。我们发现这使它更清晰,因为它更符合命名标准(即类和结构名称应该是 Pascal Case)。小写用于stringint以及其他可以声明为const的变量;使用Object 代替object,因为它不能被声明为const

标签: c# .net coding-style clr


【解决方案1】:

我怀疑这条规则来自对框架指南的误解。

指南在General Naming Conventions 部分中说:

在标识符除了其类型之外没有语义意义的极少数情况下,请使用通用公共语言运行时 (CLR) 类型名称,而不是特定于语言的名称。

例如,将数据转换为Int16 的方法应命名为ToInt16,而不是ToShort,因为ShortInt16 的特定语言类型名称。

如果您创建的标识符包含一个类型作为其名称的一部分,例如一组SomeType ReadSomeType() 方法,那么您应该使用SomeType 的实际类型名称而不是C# 别名。

使用不同语言工作的程序员可能会将不同的含义与类型相关联。例如,如果您有一个 ReadFloat() 方法,C# 程序员会假定它返回 System.Single,而 F# 程序员会假定它返回 System.Double。所以你应该把它命名为ReadSingleReadDouble

此规则不适用于您用来在代码中引用类型的简单类型名称。使用您的库的程序员永远不会看到您使用的是哪个。

【讨论】:

  • 我个人使用类型名称而不是关键字,因为使用关键字 IMO 不是很一致。所有类型都有一定的亮点,以大写字母开头,然后突然出现关键字。以此为例:void MyFunction(MyClass mc, DateTime time, int num, MyDerClass mdc)int 不适合那里,尤其是语法突出显示。我更喜欢Int32,即使我不得不习惯它(有点奇怪,特别是如果你来自另一种编程语言,而int 是唯一的选择)。所以我不太确定这是一种误解。
【解决方案2】:

推荐Class Library Developers,参考暴露的名称:

在标识符除了其类型之外没有语义含义的极少数情况下,请使用通用公共语言运行时 (CLR) 类型名称,而不是特定于语言的名称。

但是,据我所知,它从来没有被推荐过,例如内部变量。

【讨论】:

    【解决方案3】:

    对此我想不出任何理由,但我必须警告这一点,我只使用了 3.5+ 版本的框架,并且可能有一些我不知道的历史原因。基本上简单类型 (int) 只是预定义 struct 类型 (System.Int32) 的别名。一些可能会帮助您确定这样做的理由是不必要的点,直接来自 C# 语言指南...

    "简单类型通过保留字标识 (sbyte, byte, ... , int, long, ... , float, double ),但这些保留字只是 System 命名空间中预定义的 struct 类型的别名(System.SByteSystem.Byte、...、System.Int32 等)。因为简单类型别名为 @987654335 @类型,每个简单类型都有成员。例如int有在System.Int32中声明的成员和从System.Object继承的成员和类似的语句

    int i = int.MaxValue;    // System.int32.MaxValue constant.
    string s = i.ToString(); // System.Int32.ToString() instance method.
    

    是允许的。”

    这样下去,但总的意思是简单类型只是别名——就是这样。没有理由做你所描述的那样。

    我希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      如果您在多语言环境中工作,或者您正在开发框架或共享库,则此规则是有意义的。

      首先,它保证 CLS 支持所有使用的类型(请参阅1)。其次,它避免了同一类型在不同.Net语言中具有不同名称而可能造成的混淆。

      我强烈推荐这本书“框架设计指南:可重用 .Net 库的约定、惯用语和模式”一书中讨论了这个主题。

      Common Language Specification

      【讨论】:

      • "第一,它保证所有使用的类型都被 CLR 支持。"你这是什么意思?
      • @CodeInChaos 我的意思是 CLS。添加了对答案的相关参考。
      • 虽然使用符合 CLS 的类型具有某些优势,但我看不出使用实际的类型名称如何保证类型符合 CLS,而不是使用别名。我可以写UInt32 就像我写uint 一样容易。为确保符合 CLS,请使用为此设计的属性。这与关键字别名与类型名的编码风格选择是正交的。
      • 我明白为什么外部命名很重要,甚至根据 FxCop 的建议更改了一些函数名称(例如,ReadFloat() 到 ReadSingle())。但局部变量的类型是内部变量,因此与 CLS 命名标准没有直接关系。但有趣的链接,谢谢。
      猜你喜欢
      • 2014-05-24
      • 1970-01-01
      • 2015-04-29
      • 2011-04-10
      • 2021-11-06
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多