关于代码分析:C# – StyleCop – SA1121:UseBuiltInTypeAlias – 可读性规则

C# - StyleCop - SA1121: UseBuiltInTypeAlias - Readability Rules

在StyleCop帮助手册中找不到它,在So和Google上,它就在这里;)

在使用StyleCop期间,我收到一条警告:

SA1121 - UseBuiltInTypeAlias -
Readability Rules

The code uses one of the basic C#
types, but does not use the built-in
alias for the type.

Rather than using the type name or the
fully-qualified type name, the
built-in aliases for these types
should always be used: bool, byte,
char, decimal, double, short, int,
long, object, sbyte, float, string,
ushort, uint, ulong.

因此,String.Empty是错误的(取决于上述规则),String.Empty是好的。

为什么使用内置别名更好?String. Int32Int64等是否会使特殊情况下的代码复杂化?


只是澄清一下:并不是每个人都同意StyleCop的作者。win32和.net专家jeffrey richter在他的优秀著作clr via c:

The C# language specification states,"As a matter of style, use of the keyword is favored over
use of the complete system type name." I disagree with the language specification; I prefer
to use the FCL type names and completely avoid the primitive type names. In fact, I wish that
compilers didn’t even offer the primitive type names and forced developers to use the FCL
type names instead. Here are my reasons:

  • I’ve seen a number of developers confused, not knowing whether to use string
    or String in their code. Because in C# string (a keyword) maps exactly to
    System.String (an FCL type), there is no difference and either can be used. Similarly,
    I’ve heard some developers say that int represents a 32-bit integer when the application
    is running on a 32-bit OS and that it represents a 64-bit integer when the application
    is running on a 64-bit OS. This statement is absolutely false: in C#, an int always maps
    to System.Int32, and therefore it represents a 32-bit integer regardless of the OS the
    code is running on. If programmers would use Int32 in their code, then this potential
    confusion is also eliminated.

  • In C#, long maps to System.Int64, but in a different programming language, long
    could map to an Int16 or Int32. In fact, C++/CLI does treat long as an Int32.
    Someone reading source code in one language could easily misinterpret the code’s
    intention if he or she were used to programming in a different programming language.
    In fact, most languages won’t even treat long as a keyword and won’t compile code
    that uses it.

  • The FCL has many methods that have type names as part of their method names. For
    example, the BinaryReader type offers methods such as ReadBoolean, ReadInt32,
    ReadSingle, and so on, and the System.Convert type offers methods such as
    ToBoolean, ToInt32, ToSingle, and so on. Although it’s legal to write the following
    code, the line with float feels very unnatural to me, and it’s not obvious that the line is
    correct:

    1
    2
    3
    BinaryReader br = new BinaryReader(...);
    float val = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
  • Many programmers that use C# exclusively tend to forget that other programming
    languages can be used against the CLR, and because of this, C#-isms creep into the
    class library code. For example, Microsoft’s FCL is almost exclusively written in C# and
    developers on the FCL team have now introduced methods into the library such as
    Array’s GetLongLength, which returns an Int64 value that is a long in C# but not
    in other languages (like C++/CLI). Another example is System.Linq.Enumerable’s
    LongCount method.


如果您拥有自己的StringInt32等类型,而不是System.*,那么代码会变得非常复杂,请不要这样做!

最终,这是个人偏好。我到处都使用别名,但我知道有些人(例如杰弗里·里克特)建议不要使用它们。保持一致可能是个好主意,仅此而已。如果您不喜欢样式警察规则,请禁用它。

请注意,方法等的名称应使用框架名称而不是别名,以便与语言无关。这对私有/内部成员来说并不重要,但对于私有方法,您也可能拥有与公共方法相同的规则。


因为内置别名是用该语言表达概念的更自然的方式。

有些文化说足球,有些文化说足球。哪一个更合适取决于上下文。


一个类比可能会有帮助:弦是对系统的,弦就像枪是对步枪。字符串是旧语言的遗留物,它是为旧程序员提供的。C没有"内置"数据类型,这些别名是为一代"C"程序员提供的,他们对这个概念有困难。


不那么混乱?对于包含静态函数的基本数据类型(传统上它只是一个值)来说,我觉得这非常委婉。我理解如果您只是存储一个值,那么使用基本数据类型等价物,但是对于访问类的成员,在基本类型名称后面加上一个(点)似乎非常困难。


这个StyleCop规则假设使用别名可以减少对"普通语言用户"的混淆。例如,它知道"long"类型,但不知何故,它害怕"System.Int64"类型,然后困惑地看到它。我个人认为,只要代码风格保持一致就很重要,不可能满足所有人。