代码质量规则
.NET 代码分析提供旨在提高代码质量的规则。 这些规则分为设计、全球化、性能和安全性等领域。 某些规则特定于 .NET API 用法,而其他规则与通用代码质量相关。
规则索引
下表列出了代码质量分析规则。
规则 ID 和警告 | 说明 |
---|---|
CA1000:不要在泛型类型中声明静态成员 | 调用泛型类型的静态成员时,必须指定该类型的类型参数。 当调用不支持推理的泛型实例成员时,必须指定该成员的类型参数。 在上述两种情况下,用于指定类型自变量的语法不同,但很容易混淆。 |
CA1001:具有可释放字段的类型应该是可释放的 | 一个类声明并实现 System.IDisposable 类型的实例字段,但该类不实现 IDisposable。 声明 IDisposable 字段的类间接拥有非托管资源,并且应该实现 IDisposable 接口。 |
CA1002:不要公开泛型列表 | System.Collections.Generic.List<(Of <(T>)>) 是针对性能(而非继承)设计的泛型集合。 因此,List 不包含任何虚拟成员。 应改为公开针对继承设计的泛型集合。 |
CA1003:使用泛型事件处理程序实例 | 类型包含一个返回 void 的委托,其签名包含两个参数(第一个是对象,第二个是可分配给 EventArgs 的类型),以及包含的程序集面向 Microsoft .NET Framework 2.0。 |
CA1005:避免泛型类型的参数过多 | 泛型类型包含的类型参数越多,越难以知道并记住每个类型参数各代表什么。 它通常有一个类型参数,如在 List<T> 中,而在某些情况下有两个类型参数,如在 Dictionary<TKey, TValue> 中。 但是,如果存在两个以上的类型参数,则大多数用户都会感到过于困难。 |
CA1008:枚举应具有零值 | 像其他值类型一样,未初始化枚举的默认值为零。 无标志特性的枚举应通过使用零值来定义成员,这样默认值即为该枚举的有效值。 如果应用了 FlagsAttribute 特性的枚举定义值为零成员,则该成员的名称应为“None”,以指示枚举中尚未设置值。 |
CA1010:集合应实现泛型接口 | 若要扩大集合的用途,应实现某个泛型集合接口。 然后,可以使用该集合来填充泛型集合类型。 |
CA1012:抽象类型不应具有公共构造函数 | 抽象类型的构造函数只能由派生类型调用。 由于公共构造函数用于创建类型的实例,但无法为抽象类型创建实例,因此具有公共构造函数的抽象类在设计上是错误的。 |
CA1014:用 CLSCompliantAttribute 标记程序集 | 公共语言规范 (CLS) 定义了程序集在跨编程语言使用时必须符合的命名限制、数据类型和规则。 好的设计要求所有程序集用 CLSCompliantAttribute 显式指示 CLS 合规性。 如果程序集没有此特性,则该程序集即不合规。 |
CA1016:用 AssemblyVersionAttribute 标记程序集 | .NET 使用版本号来唯一标识程序集,并绑定到强名称程序集中的类型。 版本号与版本和发行者策略一起使用。 默认情况下,仅使用用于生成应用程序的程序集版本运行应用程序。 |
CA1017:用 ComVisibleAttribute 标记程序集 | ComVisibleAttribute 决定 COM 客户端如何访问托管代码。 合理的设计指出程序集将显式指示 COM 可见性。 可以设置整个程序集的 COM 可见性,然后重写各个类型和类型成员的 COM 可见性。 如果此特性不存在,则程序集的内容对 COM 客户端可见。 |
CA1018:用 AttributeUsageAttribute 标记特性 | 当定义自定义特性时,用 AttributeUsageAttribute 标记该特性,以指示源代码中可以应用自定义特性的位置。 特性的含义和预定用法将决定它在代码中的有效位置。 |
CA1019:定义特性参数的访问器 | 特性可以定义强制自变量,在对目标应用该特性时必须指定这些自变量。 这些实参也称为位置实参,因为它们将作为位置形参提供给特性构造函数。 对于每一个强制变量,特性还必须提供一个相应的只读属性,以便可以在执行时检索该变量的值。 特性还可以定义可选实参,可选实参也称为命名实参。 这些变量按名称提供给特性构造函数,并且必须具有相应的读/写属性。 |
CA1021:避免使用 out 参数 | 通过引用(使用 out 或 ref)传递类型要求具有使用指针的经验,了解值类型和引用类型的不同之处,以及能处理具有多个返回值的方法。 另外,out 和 ref 参数之间的差异没有得到广泛了解。 |
CA1024:在适用处使用属性 | 公共或受保护方法的名称以“Get”开头,没有采用任何参数或返回的值不是数组。 该方法可能很适于成为属性。 |
CA1027:用 FlagsAttribute 标记枚举 | 枚举是一种值类型,它定义一组相关的已命名常数。 如果可以按照有意义的方式组合一个枚举的已命名常数,则对该枚举应用 FlagsAttribute。 |
CA1028:枚举存储应为 Int32 | 枚举是一种值类型,它定义一组相关的已命名常数。 默认情况下,System.Int32 数据类型用于存储常量值。 尽管您可以更改此基础类型,然而对于大多数情况,既不需要,也不建议您这样做。 |
CA1030:在适用处使用事件 | 该规则检测名称通常用于事件的方法。 如果为响应明确定义的状态更改而调用一个方法,则应由事件处理程序调用该方法。 调用该方法的对象应引发事件而不是直接调用该方法。 |
CA1031:不要捕捉一般异常类型 | 不应捕捉一般异常。 捕捉更具体的异常,或者在执行 catch 块中的最后一条语句时重新引发一般异常。 |
CA1032:实现标准异常构造函数 | 如果不能提供完整的构造函数集,要正确处理异常将变得比较困难。 |
CA1033:接口方法应可由子类型调用 | 未密封的外部可见类型提供了显式实现公共接口的方法,但没有提供具有相同名称的其他外部可见方法。 |
CA1034:嵌套类型不应是可见的 | 嵌套类型是在另一个类型的范围中声明的类型。 嵌套类型用于封装包含类型的私有实现详细信息。 如果用于此用途,则嵌套类型不应是外部可见的。 |
CA1036:重写可比较类型中的方法 | 公共或受保护类型实现 System.IComparable 接口。 它不重写 Object.Equals,也不重载表示相等、不等、小于或大于的语言特定运算符。 |
CA1040:避免使用空接口 | 接口定义提供某个行为或使用协定的成员。 接口所描述的功能可以被任何类型采用,而不管该类型出现在继承层次结构中的哪个位置。 类型通过实现接口的成员来实现接口。 空接口无法定义任何成员;因此,它无法定义可以实现的协定。 |
CA1041:提供 ObsoleteAttribute 消息 | 用未指定其 ObsoleteAttribute.Message 属性的 System.ObsoleteAttribute 特性来标记类型或成员。 当编译用 ObsoleteAttribute 标记的类型或成员时,将显示该特性的 Message 属性。 这将为用户提供有关已过时的类型或成员的信息。 |
CA1043:将整型或字符串参数用于索引器 | 索引器(即索引属性)应将整型或字符串类型用于索引。 这些类型一般用于为数据结构编制索引,并且提高库的可用性。 应仅限于在设计时无法指定特定整型或字符串类型的情况下使用 Object 类型。 |
CA1044:属性不应是只写的 | 虽然可以接受且经常需要使用只读属性,但设计准则禁止使用只写属性。 这是因为允许用户设置值但又禁止该用户查看这个值不能提供任何安全性。 而且,如果没有读访问,将无法查看共享对象的状态,使其用处受到限制。 |
CA1045:不要通过引用来传递类型 | 通过引用(使用 out 或 ref)传递类型要求具有以下能力:使用指针的经验,了解值类型和引用类型的不同之处,以及能处理具有多个返回值的方法。 为一般用户进行设计的库架构师不应指望用户能熟练运用 out 或 ref 参数。 |
CA1046:不要对引用类型重载相等运算符 | 对于引用类型,相等运算符的默认实现几乎始终是正确的。 默认情况下,仅当两个引用指向同一对象时,它们才相等。 |
CA1047:不要在密封类型中声明受保护的成员 | 类型声明受保护的成员,使继承类型可以访问或重写该成员。 按照定义,不能继承密封类型,这表示不能调用密封类型上的受保护方法。 |
CA1050:在命名空间中声明类型 | 应在命名空间内声明类型以避免名称冲突,并作为一种在对象层次结构中组织相关类型的方式。 |
CA1051:不要声明可见实例字段 | 字段的主要用途应是作为实现的详细信息。 字段应为 private 或 internal,并应通过使用属性公开这些字段。 |
CA1052:应密封静态容器类型 | 公共或受保护类型仅包含静态成员,而且没有用 sealed(C# 参考)(NotInheritable) 修饰符声明该类型。 应使用 sealed 修饰符标记不希望被继承的类型,以免将其用作基类型。 |
CA1053:静态容器类型不应具有构造函数 | 公共或嵌套公共类型只声明了静态成员,但具有公共或受保护的默认构造函数。 由于调用静态成员不需要类型的示例,因此没必要使用构造函数。 为安全起见,字符串重载应使用字符串自变量调用统一资源标识符 (URI) 重载。 |
CA1054:URI 参数不应为字符串 | 如果某方法采用 URI 的字符串表示形式,则应提供采用 URI 类的实例的相应重载,该重载以安全的方式提供这些服务。 |
CA1055:URI 返回值不应是字符串 | 此规则假定该方法返回 URI。 URI 的字符串表示形式容易导致分析和编码错误,并且可造成安全漏洞。 System.Uri 类以一种安全的方式提供这些服务。 |
CA1056:URI 属性不应是字符串 | 此规则假定属性表示统一资源标识符 (URI)。 URI 的字符串表示形式容易导致分析和编码错误,并且可造成安全漏洞。 System.Uri 类以一种安全的方式提供这些服务。 |
CA1058:类型不应扩展某些基类型 | 外部可见的类型扩展某些基类型。 请使用某个备选项。 |
CA1060:将 P/Invoke 移动到 NativeMethods 类 | 平台调用方法(例如标以 System.Runtime.InteropServices.DllImportAttribute 特性的那些方法,或在 Visual Basic 中使用 Declare 关键字定义的方法)可以访问非托管代码。 这些方法应属于 NativeMethods、SafeNativeMethods 或 UnsafeNativeMethods 类。 |
CA1061:不要隐藏基类方法 | 如果派生方法的参数签名只是在类型方面有所不同,而且与基方法的参数签名中的对应类型相比,这些类型的派生方式更弱,则基类型中的方法由派生类型中的同名方法隐藏。 |
CA1062:验证公共方法的参数 | 对于传递给外部可见方法的所有引用自变量,都应检查其是否为 null。 |
CA1063:正确实现 IDisposable | 所有的 IDisposable 类型都应当正确实现 Dispose 模式。 |
CA1064:异常应该是公共的 | 内部异常仅在其自己的内部范围内可见。 当异常超出内部范围后,只能使用基异常来捕获该异常。 如果内部异常继承自 Exception、SystemException 或 ApplicationException,则外部代码将没有足够的信息来了解如何处理该异常。 |
CA1065:不要在意外的位置引发异常 | 不应引发异常的方法引发了异常。 |
CA1066:重写 Equals 时实现 IEquatable | 值类型替代 Equals 方法,但不实现 IEquatable<T>。 |
CA1067:实现 IEquatable 时重写 Equals | 类型实现 IEquatable<T>,但不替代 Equals 方法。 |
CA1068:CancellationToken 参数必须最后出现 | 方法具有 CancellationToken 参数,但它不是最后一个参数。 |
CA1069:枚举不得具有重复值 | 枚举具有多个成员,这些成员显式分配有相同常数值。 |
CA1070:不要将事件字段声明为“虚拟” | 类字段事件被声明为“虚拟”。 |
CA1200:不要使用带前缀的 cref 标记 | XML 文档标记中的 cref 属性是指“代码引用”。 它指定标记的内部文本是一个代码元素,例如类型、方法或属性。 避免使用带有前缀的 cref 标记,因为它会阻止编译器验证引用。 它还会阻止 Visual Studio 集成开发环境 (IDE) 在重构过程中查找和更新这些符号引用。 |
CA1303:请不要将文本作为本地化参数传递 | 某外部可见的方法将一个字符串字面量作为参数传递给 .NET 构造函数或方法,该字符串应该是可本地化的字符串。 |
CA1304:指定 CultureInfo | 某方法或构造函数调用的成员有一个接受 System.Globalization.CultureInfo 参数的重载,但该方法或构造函数没有调用接受 CultureInfo 参数的重载。 如果未提供 CultureInfo 或 System.IFormatProvider 对象,则重载成员提供的默认值可能不会在所有区域设置中产生您想要的效果。 |
CA1305:指定 IFormatProvider | 某方法或构造函数调用的一个或多个成员有接受 System.IFormatProvider 参数的重载,但该方法或构造函数没有调用接受 IFormatProvider 参数的重载。 如果未提供 System.Globalization.CultureInfo 或 IFormatProvider 对象,则重载成员提供的默认值可能不会在所有区域设置中产生您想要的效果。 |
CA1307:为了清晰起见,请指定 StringComparison | 字符串比较运算使用不设置 StringComparison 参数的方法重载。 |
CA1308:将字符串规范化为大写 | 字符串应正常化为大写字母。 少量字符转换为小写字母后不能再转换回来。 |
CA1309:使用按顺序的 StringComparison | 非语义的字符串比较运算不会将 StringComparison 参数设置为 Ordinal 或 OrdinalIgnoreCase。 因此,通过将参数显式设置为 StringComparison.Ordinal 或 StringComparison.OrdinalIgnoreCase,通常可以提高代码的速度、正确性和可靠性。 |
CA1310:为了确保正确,请指定 StringComparison | 字符串比较操作使用未设置 StringComparison 参数的方法重载,并默认使用区域性特定的字符串比较。 |
CA1311:指定区域性或使用固定版本 | 指定区域性或使用固定区域性,以避免在调用 ToUpper 或 ToLower 时隐式依赖当前区域性。 |
CA1401:P/Invokes 应为不可见 | 公共类型中的公共或受保护方法具有 System.Runtime.InteropServices.DllImportAttribute 属性(在 Visual Basic 中由 Declare 关键字实现)。 这些方法不能公开。 |
CA1416:验证平台兼容性 | 在组件上使用依赖于平台的 API 会使代码无法用于所有平台。 |
CA1417:请勿对 P/Invokes 的字符串参数使用 OutAttribute |
如果该字符串为暂存的字符串,则通过包含 OutAttribute 的值传递的字符串参数可能使运行时变得不稳定。 |
CA1418:使用有效的平台字符串 | 平台兼容性分析器需要有效的平台名称和版本。 |
CA1419:提供与派生自“System.Runtime.InteropServices.SafeHandle”的具体类型的包含类型一样可见的无参数构造函数 | 提供与派生自 System.Runtime.InteropServices.SafeHandle 的类型的包含类型一样可见的无参数构造函数可改进源生成的互操作解决方案的性能和使用情况。 |
CA1420:属性、类型或特性需要运行时封送 | 在禁用运行时封送时使用需要运行时封送的功能将导致运行时异常。 |
CA1421:应用 DisableRuntimeMarshallingAttribute 时,方法使用运行时封送 | 方法使用运行时封送,并且运行时封送处理已显式禁用。 |
CA1422:验证平台兼容性 | 不建议从可从该 OS(版本)访问的调用站点调用在给定 OS(版本)中过时的 API。 |
CA1501:避免过度继承 | 类型在继承层次结构中的深度超过四级。 深度嵌套的类型层次结构可能很难遵循、理解和维护。 |
CA1502:避免过度复杂 | 此规则通过方法来测量线性独立的路径的数量,该数量是由条件分支的数量和复杂度决定的。 |
CA1505:避免使用无法维护的代码 | 类型或方法具有较低的可维护性索引值。 如果可维护性指数较低,则表示类型或方法可能难以维护,最好重新进行设计。 |
CA1506:避免过度类耦合度 | 此规则通过计算类型或方法包含的唯一类型引用的个数来衡量类耦合。 |
CA1507:使用 nameof 代替字符串 | 字符串字面量用作参数,可在其中使用 nameof 表达式。 |
CA1508:避免死条件代码 | 方法具有在运行时计算结果始终为 true 或 false 的条件代码。 这会导致条件的 false 分支中出现死代码。 |
CA1509:代码度量配置文件中的条目无效 | 代码度量规则(如 CA1501、CA1502、CA1505 和 CA1506)提供了具有无效条目的名为 CodeMetricsConfig.txt 的配置文件。 |
CA1510:使用 ArgumentNullException 引发帮助程序 | 与使用构造新的异常实例的 if 块相比,使用引发帮助程序更简单、更高效。 |
CA1511:使用 ArgumentException 引发帮助程序 | 与使用构造新的异常实例的 if 块相比,使用引发帮助程序更简单、更高效。 |
CA1512:使用 ArgumentOutOfRangeException 引发帮助程序 | 与使用构造新的异常实例的 if 块相比,使用引发帮助程序更简单、更高效。 |
CA1513:使用 ObjectDisposedException 引发帮助程序 | 与使用构造新的异常实例的 if 块相比,使用引发帮助程序更简单、更高效。 |
CA1514:避免冗余长度参数 | 切片到字符串或缓冲区末尾时使用冗余长度参数。 计算出的长度可能容易出错,而且也是不必要的。 |
CA1515:考虑将公共类型变为内部 | 与类库不同,应用程序的 API 通常不会公开引用,因此可以将类型标记为内部。 |
CA1700:不要命名“Reserved”枚举值 | 此规则假定当前不使用名称中包含“reserved”的枚举成员,而是将其作为一个占位符,以在将来的版本中重命名或移除它。 重命名或移除成员是一项重大更改。 |
CA1707:标识符不应包含下划线 | 按照约定,标识符名称不包含下划线 (_) 字符。 该规则将检查命名空间、类型、成员和参数。 |
CA1708:标识符应以大小写之外的差别进行区分 | 不能仅通过大小写区分命名空间、类型、成员和参数的标识符,因为针对公共语言运行时的语言不需要区分大小写。 |
CA1710:标识符应具有正确的后缀 | 按照约定,扩展某些基类型或实现某些接口的类型的名称,或者由这些类型派生的类型的名称应具有与相应基类型或接口关联的后缀。 |
CA1711:标识符应采用正确的后缀 | 按照约定,只有扩展某些基类型或实现某些接口的类型的名称或者从这些类型派生的类型的名称,应该以特定的保留后缀结尾。 其他类型名称不应使用这些保留的后缀。 |
CA1712:不要将类型名用作枚举值的前缀 | 枚举成员的名称不能使用类型名称作为前缀,因为类型信息将由开发工具提供。 |
CA1713:事件不应具有 before 或 after 前缀 | 事件的名称以“Before”或“After”开头。 若要命名按特定顺序引发的相关事件,请使用现在时或过去时指示一系列操作中的相对位置。 |
CA1714:Flags 枚举应采用复数形式的名称 | 公共枚举具有 System.FlagsAttribute 特性并且其名称不是以“s”结尾。 用 FlagsAttribute 标记的类型具有复数形式的名称,因为该特性指明可以指定多个值。 |
CA1715:标识符应具有正确的前缀 | 外部可见的接口的名称不以大写的“I”开头。 外部可见的类型或方法上的泛型类型参数的名称不以大写的“T”开头。 |
CA1716:标识符不应与关键字冲突 | 某个命名空间名称或类型名称与编程语言中的保留关键字相同。 命名空间和类型的标识符不应与针对公共语言运行时的语言所定义的关键字冲突。 |
CA1717:只有 FlagsAttribute 枚举应采用复数形式的名称 | 命名约定规定,复数形式的枚举名称表示可以同时指定多个枚举值。 |
CA1720:标识符不应包含类型名称 | 外部可见成员中的某个参数的名称包含一个数据类型名称,或者外部可见成员的名称包含一个语言特定的数据类型名称。 |
CA1721:属性名不应与 get 方法冲突 | 公共或受保护成员的名称以“Get”开头,且其余部分与公共或受保护属性的名称匹配。 “Get”方法和属性的名称应能够明确区分其功能上的差异。 |
CA1724:类型名不应与命名空间冲突 | 类型名不应与 .NET 命名空间的名称匹配。 与该规则冲突将使库的可用性下降。 |
CA1725:参数名应与基方法中的声明保持一致 | 以一致的方式命名重写层次结构中的参数可以提高方法重写的可用性。 如果派生方法中的参数名与基声明中的名称不同,可能会导致无法区分出该方法是基方法的重写还是该方法的新重载。 |
CA1727:将 PascalCase 用于已命名占位符 | 在日志记录消息模板中将 PascalCase 用于已命名占位符。 |
CA1801:检查未使用的参数 | 方法签名包含一个没有在方法体中使用的参数。 |
CA1802:在合适的位置使用文本 | 某个字段被声明为 static 和 read-only(在 Visual Basic 中为 Shared 和 ReadOnly),并使用可在编译时计算的值初始化。 因为赋给目标字段的值可在编译时计算,因此请将声明更改为 const(在 Visual Basic 中为 Const)字段,以便在编译时而非运行时计算值。 |
CA1805:避免进行不必要的初始化 | 在运行构造函数之前,.NET 运行时将引用类型的所有字段初始化为其默认值。 在大多数情况下,将字段显式初始化为其默认值是冗余的,这会增加维护成本,并可能会降低性能(如程序集大小增加)。 |
CA1806:不要忽略方法结果 | 创建一个新对象,但从不使用该对象;或者调用会创建并返回一个新字符串的方法,但从不使用这个新字符串;或者 COM 或 P/Invoke 方法返回一个从不使用的 HRESULT 或错误代码。 |
CA1810:以内联方式初始化引用类型的静态字段 | 当一个类型声明显式静态构造函数时,实时 (JIT) 编译器会向该类型的每个静态方法和实例构造函数中添加一项检查,以确保之前已调用该静态构造函数。 静态构造函数检查会降低性能。 |
CA1812:避免未实例化的内部类 | 程序集级别类型的实例不是由程序集中的代码创建的。 |
CA1813:避免使用非密封特性 | .NET 提供用于检索自定义属性的方法。 默认情况下,这些方法搜索特性继承层次结构。 通过密封特性,将无需搜索继承层次结构,且能够提高性能。 |
CA1814:与多维数组相比,首选使用交错数组 | 交错数组是元素为数组的数组。 构成元素的数组可以是不同的大小,以减少某些数据集的浪费空间。 |
CA1815:重写值类型上的 Equals 和相等运算符 | 对于值类型,Equals 的继承的实现使用反射库,并比较所有字段的内容。 反射需要消耗大量计算资源,可能没有必要比较每一个字段是否相等。 如果希望用户对实例进行比较或排序,或者希望用户将实例用作哈希表键,则值类型应实现 Equals。 |
CA1816:正确调用 GC.SuppressFinalize | Dispose 实现的方法不调用 GC。SuppressFinalize;或不是 Dispose 调用 GC 的实现的方法。SuppressFinalize;或方法调用 GC。SuppressFinalize 并传递其他内容(Visual Basic 中的 Me)。 |
CA1819:属性不应返回数组 | 即使属性是只读的,该属性返回的数组也不是写保护的。 若要使数组不会被更改,属性必须返回数组的副本。 通常,用户不能理解调用这种属性的负面性能影响。 |
CA1820:使用字符串长度测试是否有空字符串 | 使用 String.Length 属性或 String.IsNullOrEmpty 方法比较字符串要比使用 Equals 的速度快得多。 |
CA1821:移除空终结器 | 应尽可能避免终结器,因为跟踪对象生存期会产生额外的性能系统开销。 空的终结器只会徒增系统开销,没有一点好处。 |
CA1822:将成员标记为 static | 可以将不访问实例数据或不调用实例方法的成员标记为 static(在 Visual Basic 中为 Shared)。 在将这些方法标记为 static 之后,编译器将向这些成员发出非虚拟调用站点。 这会使性能敏感的代码的性能得到显著提高。 |
CA1823:避免未使用的私有字段 | 检测到程序集内有似乎未访问过的私有字段。 |
CA1824:用 NeutralResourcesLanguageAttribute 标记程序集 | NeutralResourcesLanguage 特性通知资源管理器用于显示程序集的非特定区域性资源的语言。 这将改进所加载的第一个资源的查找性能,并缩小工作集。 |
CA1825:避免数组分配长度为零 | 初始化长度为零的数组将导致不必要的内存分配。 相反,请通过调用 Array.Empty 来使用静态分配的空数组实例。 内存分配在此方法的所有调用之间共享。 |
CA1826:使用属性,而不是 Linq Enumerable 方法 | 对支持等效且更有效的属性的类型使用了 Enumerable LINQ 方法。 |
CA1827:如果可以使用 Any,请勿使用 Count/LongCount | 在使用 Any 方法会更有效的情况下使用了 Count 或 LongCount 方法。 |
CA1828:如果可以使用 AnyAsync,请勿使用 CountAsync/LongCountAsync | 在使用 AnyAsync 方法会更有效的情况下使用了 CountAsync 或 LongCountAsync 方法。 |
CA1829:使用 Length/Count 属性,而不是 Enumerable.Count 方法 | 对支持等效且更有效的 Length 或 Count 属性的类型使用了 Count LINQ 方法。 |
CA1830:在 StringBuilder 上优先使用强类型“追加和插入”方法重载 | Append 和 Insert 为除 String 之外的多种类型提供重载。 在可能的情况下,请首先使用强类型重载,而不是使用 ToString () 和基于字符串的重载。 |
CA1831:在合适的情况下,为字符串使用 AsSpan 而不是基于范围的索引器 | 对字符串使用范围索引器并向 ReadOnlySpan<char> 类型隐式赋值时,将使用方法 Substring 而非 Slice,这会生成字符串请求部分的副本。 |
CA1832:使用 AsSpan 或 AsMemory 而不是基于范围的索引器来获取数组的 ReadOnlySpan 或 ReadOnlyMemory 部分 | 对字符串使用范围索引器并向 ReadOnlySpan<T> 或 ReadOnlyMemory<T> 类型隐式赋值时,将使用方法 GetSubArray 而非 Slice,这会生成数组请求部分的副本。 |
CA1833:使用 AsSpan 或 AsMemory 而不是基于范围的索引器来获取数组的 Span 或 Memory 部分 | 对字符串使用范围索引器并向 Span<T> 或 Memory<T> 类型隐式赋值时,将使用方法 GetSubArray 而非 Slice,这会生成数组请求部分的副本。 |
CA1834:对单字符字符串使用 StringBuilder.Append(char) | StringBuilder 具有将 char 用作其参数的 Append 重载。 优先选择调用 char 重载以提高性能。 |
CA1835:对于“ReadAsync”和“WriteAsync”,首选基于“Memory”的重载 | “Stream”有一个将“Memory<byte>”用作第一个参数的“ReadAsync”重载和一个将“ReadOnlyMemory<Byte>”用作第一个参数的“WriteAsync”重载。 优先选择调用基于内存的重载,它们更有效。 |
CA1836:如可用,首选 IsEmpty 而不是 Count |
首选比 Count 、Length 、Count<TSource>(IEnumerable<TSource>) 或 LongCount<TSource>(IEnumerable<TSource>) 更有效的 IsEmpty 属性,以确定对象是否包含任何项目。 |
CA1837:使用 Environment.ProcessId 而不是 Process.GetCurrentProcess().Id |
Environment.ProcessId 比 Process.GetCurrentProcess().Id 更简单、更快速。 |
CA1838:避免对 P/Invokes 使用 StringBuilder 参数 |
“StringBuilder”的封送处理总是会创建一个本机缓冲区副本,这导致一个封送处理操作出现多次分配。 |
CA1839:使用 Environment.ProcessPath 而不是 Process.GetCurrentProcess().MainModule.FileName | Environment.ProcessPath 比 Process.GetCurrentProcess().MainModule.FileName 更简单、更快速。 |
CA1840:使用 Environment.CurrentManagedThreadId 而不是 Thread.CurrentThread.ManagedThreadId | Environment.CurrentManagedThreadId 比 Thread.CurrentThread.ManagedThreadId 更紧凑、更高效。 |
CA1841:首选字典包含方法 | 调用Contains Keys 或集合通常比调用ContainsKey 或Values ContainsValue 字典本身更昂贵。 |
CA1842:不要对单个任务使用“WhenAll” | 与 WhenAll 单个任务一起使用可能会导致性能损失。 请改为等待或返回任务。 |
CA1843:不要对单个任务使用“WaitAll” | 与 WaitAll 单个任务一起使用可能会导致性能损失。 请改为等待或返回任务。 |
CA1844:对“流”进行子分类时,提供异步方法的基于内存的重写 | 若要提高性能,请在对“流”进行子分类时重写基于内存的异步方法。 然后,在基于内存的方法中实现基于数组的方法。 |
CA1845:使用基于跨度的“string.Concat” | 使用 AsSpan 和 string.Concat 比使用 Substring 和串联运算符更高效。 |
CA1846:首选 AsSpan ,次选 Substring |
AsSpan 比 Substring 更高效。 Substring 执行 O(n) 字符串复制,而 AsSpan 不会执行此操作且具有固定成本。 AsSpan 也不执行任何堆分配。 |
CA1847:对单个字符查找使用 char 文本 | 搜索单个字符时使用 String.Contains(char) 而不是 String.Contains(string) 。 |
CA1848:使用 LoggerMessage 委托 | 为了提高性能,请使用 LoggerMessage 委托。 |
CA1849:当在异步方法中时,调用异步方法 | 在已属于异步的方法中,对其他方法的调用应指向其存在的异步版本。 |
CA1850:首选静态 HashData 方法,而非 ComputeHash |
相比创建并管理 HashAlgorithm 实例来调用 ComputeHash ,使用静态 HashData 方法更高效。 |
CA1851:可能多次枚举了 IEnumerable 集合 |
可能多次枚举了 IEnumerable 集合。 请考虑使用避免多次枚举的实现。 |
CA1852:密封内部类型 | 在其程序集外部不可访问且其包含程序集中没有子类型的类型不会密封。 |
CA1853:对“Dictionary.ContainsKey(key)”的不必要调用 | 无需使用 Dictionary.ContainsKey(key) 保护 Dictionary.Remove(key) 。 Dictionary<TKey,TValue>.Remove(TKey) 已检查密钥是否存在,如果不存在,则不会引发异常。 |
CA1854:首选“IDictionary.TryGetValue(TKey, out TValue)”方法 | 首选“TryGetValue”而不是受“ContainsKey”检查保护的字典索引器访问。 “ContainsKey”和索引器都查找键,因此使用“TryGetValue”可避免额外的查找。 |
CA1855:使用 Span<T>.Clear() 而不是 Span<T>.Fill() | 若要使用默认值填充某范围的元素,调用 Span<T>.Clear() 比调用 Span<T>.Fill(T) 更高效。 |
CA1856:ConstantExpected 属性的用法不正确 | 未在参数上正确应用 ConstantExpectedAttribute 属性。 |
CA1857:该参数需要一个常量来获得最佳性能。 | 向通过 ConstantExpectedAttribute 注释的参数传递了无效的自变量。 |
CA1858:使用 StartsWith 而不是 IndexOf | 与调用 String.IndexOf 相比,调用 String.StartsWith 检查字符串是否以给定前缀开头更高效。 |
CA1859:尽可能使用具体类型来提高性能 | 代码使用接口类型或抽象类型,导致不必要的接口调用或虚拟调用。 |
CA1860:避免使用“Enumerable.Any()”扩展方法 | 相比调用 Enumerable.Any 来确定集合类型是否具有任何元素,使用 Length 、Count 或 IsEmpty (如果可能)来确定将更有效、更清晰。 |
CA1861:避免将常量数组用作参数 | 不会重复使用作为参数传递的常量数组,这意味着会产生性能开销。 请考虑将它们提取到“静态只读”字段中,以提高性能。 |
CA1862:使用“StringComparison”方法重载执行不区分大小写的字符串比较 | 当代码调用 ToLower() 或 ToUpper() 执行不区分大小写的字符串比较时,将执行不必要的分配。 |
CA1863:使用“CompositeFormat” | 若要降低格式设置成本,请缓存并使用 CompositeFormat 实例作为参数 String.Format 或 StringBuilder.AppendFormat 。 |
CA1864:首选“IDictionary.TryAdd(TKey, TValue)”方法 | Dictionary<TKey,TValue>.ContainsKey(TKey) 和 Dictionary<TKey,TValue>.Add 都执行查找操作,这是冗余设置。 调用 Dictionary<TKey,TValue>.TryAdd 更高效,后者返回 bool ,指示是否添加了值。 如果键已存在,则 TryAdd 不会覆盖该键的值。 |
CA1865-CA1867:使用 char 重载 | 对于单字符串,char 重载的性能更好。 |
CA1868:针对集的对“Contains”不必要调用 | ISet<T>.Add(T) 和 ICollection<T>.Remove(T) 都会执行查找,这使得事先调用 ICollection<T>.Contains(T) 变得多余。 直接调用 Add(T) 或 Remove(T) 更高效,此方法会返回一个布尔值,指示是已添加还是已删除项。 |
CA1869:缓存并重用“JsonSerializerOptions”实例 | 如果你的代码执行多次,则使用 JsonSerializerOptions 的本地实例进行序列化或反序列化可能会大幅降低应用程序的性能,因为 System.Text.Json 会在内部将序列化相关的元数据缓存到提供的实例中。 |
CA1870:使用缓存的“SearchValues”实例 | 与将值直接传递给“IndexOfAny”或“ContainsAny”相比,使用缓存的 SearchValues<T> 更加高效。 |
CA1871:不要将可为 null 的结构传递给“ArgumentNullException.ThrowIfNull” | “ArgumentNullException.ThrowIfNull”接受“object”,因此传递可为 null 的结构可能会导致装箱值。 |
CA1872:首选“Convert.ToHexString”和“Convert.ToHexStringLower”,而不是基于“BitConverter.ToString”的调用链 | 使用 Convert.ToHexString 或 Convert.ToHexStringLower 将字节编码为十六进制字符串表示形式。 与结合使用BitConverter.ToStringString.Replace替换短划线和替换短划线相比,这些方法更加高效和String.ToLower分配友好。 |
CA2000:丢失范围之前释放对象 | 由于可能发生异常事件,导致对象的终结器无法运行,因此,应显式释放对象,以避免对该对象的所有引用超出范围。 |
CA2002:不要锁定具有弱标识的对象 | 当可以跨应用程序域边界直接进行访问对象时,则认为该对象具有弱标识。 对于尝试获取对具有弱标识的对象的锁的线程,该线程可能会被其他应用程序域中持有对同一对象的锁的另一线程所阻止。 |
CA2007:不直接等待任务 | 异步方法会直接等待Task。 异步方法直接等待 Task 时,延续任务出现在创建任务的同一线程中。 此行为可能会降低性能,并且可能会导致 UI 线程发生死锁。 请考虑调用 Task.ConfigureAwait(Boolean) 以表示延续任务意图。 |
CA2008:不要在未传递 TaskScheduler 的情况下创建任务 | 任务创建或延续操作使用未指定 TaskScheduler 参数的方法重载。 |
CA2009:请勿对 ImmutableCollection 值调用 ToImmutableCollection | 没有必要在 System.Collections.Immutable 命名空间的不可变集合上调用 ToImmutable 方法。 |
CA2011:请勿在其资源库中分配属性 | 属性在自身的 set 访问器中被意外赋值。 |
CA2012:正确使用 ValueTask | 从成员调用中返回的 ValueTasks 旨在直接等待。 尝试多次使用 ValueTask 或直接访问其结果,然后才能知道已完成可能会导致异常或损坏。 忽略此类 ValueTask 可能是功能 bug 的指示,可能会降低性能。 |
CA2013:请勿将 ReferenceEquals 与值类型结合使用 | 使用 System.Object.ReferenceEquals 比较值时,如果 objA 和 objB 是值类型,则在将其传递给 ReferenceEquals 方法之前将它们装箱。 这意味着,即使 objA 和 objB 都表示值类型的同一个实例,ReferenceEquals 方法也会返回 false。 |
CA2014:请勿在循环中使用 stackalloc。 | 仅在当前方法调用结束时,Stackalloc 分配的堆栈空间才会释放。 在循环中使用此方法可能导致无限堆栈增长,最终出现堆栈溢出的情况。 |
CA2015:请勿为派生自 MemoryManager<T> 的类型定义终结器 | 将终结器添加到派生自MemoryManager<T>的类型可能会允许内存释放,而内存仍在由 a.Span<T> |
CA2016:将 CancellationToken 参数转发到采用一个该参数的方法 | 将 CancellationToken 参数转发给方法来确保操作取消通知得到正确传播,或者在 CancellationToken.None 中显式传递,以指示有意不传播令牌。 |
CA2017:参数计数不匹配 | 日志记录消息模板中所提供参数的数量与已命名占位符的数量不匹配。 |
CA2018:Buffer.BlockCopy 的 count 参数应指定要复制的字节数 |
使用 Buffer.BlockCopy 时,count 参数指定要复制的字节数。 应仅对元素大小正好为一个字节的数组将 Array.Length 用于 count 参数。 byte 、sbyte 和 bool 数组具有大小为一个字节的元素。 |
CA2019:ThreadStatic 字段不应使用内联初始化 |
使用 ThreadStaticAttribute 注释的字段在 static 构造函数(在 Visual Basic 中是 Shared 构造函数)进行内联或显式初始化。 |
CA2020:防止 IntPtr/UIntPtr 的内置运算符导致的行为更改 | .NET 7 中添加的一些内置运算符的行为与 .NET 6 及更早版本中的用户定义运算符的行为不同。 某些用于在未检查上下文中引发的运算符,除非在检查的上下文中包装,否则溢出不再引发。 以前未在检查上下文中引发的某些运算符现在会引发,除非包装在未选中的上下文中。 |
CA2021:不要使用不兼容类型调用 Enumerable.Cast<T> 或 Enumerable.OfType<T> | 调用 Enumerable.Cast<TResult>(IEnumerable) 或 Enumerable.OfType<TResult>(IEnumerable) 会指定与输入集合的类型不兼容的类型参数。 |
CA2100:检查 SQL 查询是否存在安全漏洞 | 一个方法使用按该方法的字符串参数生成的字符串设置 System.Data.IDbCommand.CommandText 属性。 此规则假定字符串参数中包含用户输入。 基于用户输入生成的 SQL 命令字符串易于受到 SQL 注入式攻击。 |
CA2101:指定对 P/Invoke 字符串参数进行封送处理 | 某平台调用成员允许部分受信任的调用方,具有一个字符串参数,并且不显式封送该字符串。 这可能导致潜在的安全漏洞。 |
CA2109:检查可见的事件处理程序 | 检测到公共事件处理方法或受保护事件处理方法。 除非绝对必要,否则不应公开事件处理方法。 |
CA2119:密封满足私有接口的方法 | 可继承的公共类型为 internal(在 Visual Basic 中为 Friend)接口提供可重写的方法实现。 若要修复与此规则的冲突,请禁止方法在程序集外重写。 |
CA2153:避免处理损坏状态异常 | 损坏状态异常 (CSE) 指示进程中存在内存损坏。 如果攻击者可以将攻击放置到损坏的内存区域,则捕获它们(而非允许进程崩溃)可能导致安全漏洞。 |
CA2200:再次引发以保留堆栈详细信息 | 再次引发某个异常,在 throw 语句中显式指定了该异常。 如果通过在 throw 语句中指定异常来重新引发该异常,则引发该异常的原始方法与当前方法之间的方法调用的列表将丢失。 |
CA2201:不要引发保留的异常类型 | 这使得很难检测和调试原始错误。 |
CA2207:以内联方式初始化值类型的静态字段 | 某值类型声明了显式静态构造函数。 要修复与该规则的冲突,请在声明它时初始化所有静态数据并移除静态构造函数。 |
CA2208:正确实例化参数异常 | 对异常类型的默认(无参数)构造函数进行调用,或者 ArgumentException 将不正确的字符串参数传递给异常类型的参数化构造函数,该构造函数派生自 ArgumentException 该异常类型。 |
CA2211:非常量字段不应是可见的 | 不是常数也不是只读字段的静态字段不是线程安全的。 必须严格控制对这类字段的访问,并需要高级编程技术来同步对类对象的访问。 |
CA2213:应释放可释放的字段 | 实现 System.IDisposable 的类型声明了同样实现 IDisposable 的类型的字段。 字段的 Dispose 方法不由声明类型的 Dispose 方法调用。 |
CA2214:不要在构造函数中调用可重写的方法 | 当构造函数调用虚拟方法时,调用该方法的实例的构造函数可能尚未执行。 |
CA2215:Dispose 方法应调用基类释放 | 如果类型继承自可释放类型,则必须从它自己的 Dispose 方法中调用基类型的 Dispose 方法。 |
CA2216:可释放类型应声明终结器 | 实现 System.IDisposable 并包含建议使用非托管资源的字段的类型未实现 Object.Finalize 所描述的终结器。 |
CA2217:不要使用 FlagsAttribute 标记枚举 | 外部可见的枚举使用 FlagsAttribute 标记,并且它包含的一个或多个值不是 2 的幂或不是为该枚举定义的其他值的组合。 |
CA2218:重写 Equals 时重写 GetHashCode | 公共类型重写 System.Object.Equals,但不重写 System.Object.GetHashCode。 |
CA2219:在异常子句中不引发异常 | 如果在 finally 或 fault 子句中引发异常,新异常将隐藏活动异常。 当在 filter 子句中引发异常时,运行时会在不提示的情况下捕捉异常。 这使得很难检测和调试原始错误。 |
CA2224:重载相等运算符时重写 Equals 方法 | 公共类型会实现相等运算符,但不重写 System.Object.Equals。 |
CA2225:运算符重载具有命名的备用项 | 检测到运算符重载,但未找到预期的指定备用方法。 命名的备用成员提供了对与运算符相同的功能的访问,它提供给开发人员,在用不支持重载运算符的语言进行编程时使用。 |
CA2226:运算符应有对称重载 | 某个类型实现了相等运算符或不等运算符,却未实现相反运算符。 |
CA2227:集合属性应为只读 | 使用可写的集合属性,用户可以将该集合替换为不同的集合。 只读属性禁止替换该集合,但仍允许设置单个成员。 |
CA2229:实现序列化构造函数 | 要修复与该规则的冲突,请实现序列化构造函数。 对于密封类,请使构造函数成为私有;否则,请使构造函数成为受保护。 |
CA2231:重写 ValueType.Equals 时应重载相等运算符 | 值类型重写 Object.Equals,但未实现相等运算符。 |
CA2234:传递 System.Uri 对象,而不传递字符串 | 调用了带有一个字符串参数的方法,该参数的名称中包含“uri”、“URI”、“urn”、“URN”、“url”或“URL”。 此方法的声明类型包含具有 System.Uri 参数的对应方法重载。 |
CA2235:标记所有不可序列化的字段 | 在可以序列化的类型中声明了类型不可序列化的实例字段。 |
CA2237:用 SerializableAttribute 标记 ISerializable 类型 | 若要被公共语言运行时识别为可序列化,类型必须用 SerializableAttribute 特性标记,即使该类型通过实现 ISerializable 接口使用了自定义的序列化例程也是如此。 |
CA2241:为格式化方法提供正确的参数 | 传递给 System.String.Format 的 format 自变量不包含对应于每个对象自变量的格式项,反之亦然。 |
CA2242:正确测试 NaN | 此表达式对照 Single.Nan 或 Double.Nan 测试某个值。 使用 Single.IsNan(Single) 或 Double.IsNan(Double) 测试该值。 |
CA2243:特性字符串文本应正确分析 | 特性的字符串文本参数不能正确解析为 URL、GUID 或版本。 |
CA2244:不要复制已索引的元素初始值设定项 | 对象初始值设定项有多个具有相同常量索引的索引元素初始值设定项。 除最后一个初始值设定项之外,其余都是冗余的。 |
CA2245:请勿将属性分配给其自身 | 属性意外赋值给了其自身。 |
CA2246:请勿在同一语句中分配符号及其成员 | 不建议在同一语句中分配符号及其成员(即字段或属性)。 目前尚不清楚成员访问是打算在赋值之前使用符号的旧值还是打算使用此语句中赋值的新值。 |
CA2247:传递给 TaskCompletionSource 构造函数的参数应为 TaskCreationOptions 枚举,而不是 TaskContinuationOptions 枚举。 | TaskCompletionSource 既有采用控制基础任务的 TaskCreationOptions 的构造函数,也有采用任务中存储的对象状态的构造函数。 如果意外传递 TaskContinuationOptions 而不是 TaskCreationOptions,则将导致调用将选项视为状态。 |
CA2248:向 Enum.HasFlag 提供正确的 enum 实参 | 作为实参传递给 HasFlag 方法调用的枚举类型不同于调用枚举类型。 |
CA2249:请考虑使用 String.Contains 而不是 String.IndexOf | 对 string.IndexOf 的调用(其结果用于检查是否存在子字符串)可以用 string.Contains 替换。 |
CA2250:使用 ThrowIfCancellationRequested |
ThrowIfCancellationRequested 自动检查令牌是否已取消,如果已取消,则引发 OperationCanceledException 。 |
CA2251:使用 String.Equals 代替 String.Compare |
与其将 String.Compare 的结果与零进行比较,不如使用 String.Equals ,这样更清晰且速度可能更快。 |
CA2252:选择预览功能 | 使用预览 API 之前选择预览功能。 |
CA2253:已命名占位符不应是数值 | 日志记录消息模板中的已命名占位符不应仅由数值字符组成。 |
CA2254:模板应为静态表达式 | 日志记录消息模板不应因调用而异。 |
CA2255:不应在库中使用 ModuleInitializer 属性 |
模块初始值设定项旨在由应用程序代码使用,以确保在应用程序代码开始执行之前初始化应用程序的组件。 |
CA2256:在父接口中声明的所有成员必须在具有 DynamicInterfaceCastableImplementation 特性的接口中具有实现 | 具有特性 DynamicInterfaceCastableImplementationAttribute 的类型为一个用于实现 IDynamicInterfaceCastable 类型的类型充当接口实现。 因此,它必须提供继承接口中定义的所有成员的实现,因为若非如此,实现 IDynamicInterfaceCastable 的类型将不会提供它们。 |
CA2257:在具有“DynamicInterfaceCastableImplementationAttribute”的接口上定义的成员应为“static” | 由于实现 IDynamicInterfaceCastable 的类型可能不会在元数据中实现动态接口,因此对不是在此类型上定义的显式实现的实例接口成员的调用可能会在运行时失败。 将新接口成员标记为 static 可避免运行时错误。 |
CA2258:不支持在 Visual Basic 中提供“DynamicInterfaceCastableImplementation”接口 | 提供具有 DynamicInterfaceCastableImplementationAttribute 特性的功能性接口需要“默认接口成员”功能,这在 Visual Basic 中不受支持。 |
CA2259:确保 ThreadStatic 仅与静态字段一起使用 |
ThreadStaticAttribute 仅影响 static (在 Visual Basic 中为 Shared )字段。 在应用于实例字段时,该属性对行为没有影响。 |
CA2260:正确实现泛型数学接口 | 泛型数学接口要求将派生类型本身用于自重复类型参数。 |
CA2261:请勿结合使用 ConfigureAwaitOptions.SuppressThrowing 与 Task<TResult> |
泛型 Task<TResult> 不支持 ConfigureAwaitOptions.SuppressThrowing 选项,因为这可能会导致返回无效 TResult 。 |
CA2262:正确设置 MaxResponseHeadersLength |
确保正确提供 MaxResponseHeadersLength 值。 此值以千字节为单位。 |
CA2263:在已知类型时首选泛型重载 | 使用泛型重载最好是在已知类型时传递 System.Type 参数,因为它们通过改进的编译时检查来提升更简洁、更安全的类型代码。 |
CA2264:不要将不可为 null 的值传递给“ArgumentNullException.ThrowIfNull” | 当传递的参数为“null”时,将引发“ArgumentNullException.ThrowIfNull”。 某些构造(如不可为 null 的结构)和“nameof()”和“new”表达式已知永远不会为 null,因此“ArgumentNullException.ThrowIfNull”永远不会引发。 |
CA2300:请勿使用不安全的反序列化程序 BinaryFormatte | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2301:在未先设置 BinaryFormatter.Binder 的情况下,请不要调用 BinaryFormatter.Deserialize | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2302:在调用 BinaryFormatter.Deserialize 之前,确保设置 BinaryFormatter.Binder | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2305:请勿使用不安全的反序列化程序 LosFormatter | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2310:请勿使用不安全的反序列化程序 NetDataContractSerializer | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2311:在未先设置 NetDataContractSerializer.Binder 的情况下,请不要反序列化 | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2312:确保在反序列化之前设置 NetDataContractSerializer.Binder | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2315:请勿使用不安全的反序列化程序 ObjectStateFormatter | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2321:请勿使用 SimpleTypeResolver 对 JavaScriptSerializer 进行反序列化 | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2322:确保在反序列化之前没有使用 SimpleTypeResolver 初始化 JavaScriptSerializer | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2326:请勿使用 None 以外的 TypeNameHandling 值 | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2327:不要使用不安全的 JsonSerializerSettings | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2328:确保 JsonSerializerSettings 是安全的 | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2329:不要使用不安全的配置反序列化 JsonSerializer | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2330:在反序列化时确保 JsonSerializer 具有安全配置 | 反序列化不受信任的数据时,会对不安全的反序列化程序造成风险。 攻击者可能会修改序列化数据,使其包含非预期类型,进而注入具有不良副作用的对象。 |
CA2350:确保 DataTable.ReadXml() 的输入受信任 | 对包含不受信任的输入的 DataTable 执行反序列化时,攻击者可能通过创建恶意输入实施拒绝服务攻击。 可能存在未知的远程代码执行漏洞。 |
CA2351:确保 DataSet.ReadXml() 的输入受信任 | 对包含不受信任的输入的 DataSet 执行反序列化时,攻击者可能通过创建恶意输入实施拒绝服务攻击。 可能存在未知的远程代码执行漏洞。 |
CA2352:可序列化类型中的不安全 DataSet 或 DataTable 容易受到远程代码执行攻击 | 带有 SerializableAttribute 标记的类或结构包含 DataSet 或 DataTable 字段或属性,但不具有 GeneratedCodeAttribute。 |
CA2353:可序列化类型中的不安全 DataSet 或 DataTable | 使用 XML 序列化特性或数据协定特性进行了标记的类或结构包含 DataSet 或 DataTable 字段或属性。 |
CA2354:反序列化对象图中的不安全 DataSet 或 DataTable 可能容易受到远程代码执行攻击 | 当使用序列化的 System.Runtime.Serialization.IFormatter 进行反序列化时,且强制转换的类型的对象图可能包含 DataSet 或 DataTable 时。 |
CA2355:反序列化对象图中的不安全 DataSet 或 DataTable | 当强制转换的或指定的类型的对象图可能包含 DataSet 或 DataTable 类时,进行反序列化。 |
CA2356:Web 反序列化的对象图中不安全的 DataSet 或 DataTable | 具有 System.Web.Services.WebMethodAttribute 或 System.ServiceModel.OperationContractAttribute 具有可能引用 DataSet 或 DataTable具有参数的方法。 |
CA2361:请确保包含 DataSet.ReadXml() 的自动生成的类没有与不受信任的数据一起使用 | 对包含不受信任的输入的 DataSet 执行反序列化时,攻击者可能通过创建恶意输入实施拒绝服务攻击。 可能存在未知的远程代码执行漏洞。 |
CA2362:自动生成的可序列化类型中不安全的数据集或数据表易受远程代码执行攻击 | 当反序列化具有 BinaryFormatter 的不受信任的输入且反序列化的对象图包含 DataSet 或 DataTable 时,攻击者可能创建执行远程代码执行攻击的恶意有效负载。 |
CA3001:查看 SQL 注入漏洞的代码 | 使用不受信任的输入和 SQL 命令时,请注意防范 SQL 注入攻击。 SQL 注入攻击可以执行恶意的 SQL 命令,从而降低应用程序的安全性和完整性。 |
CA3002:查看 XSS 漏洞的代码 | 在处理来自 Web 请求的不受信任的输入时,请注意防范跨站脚本 (XSS) 攻击。 XSS 攻击会将不受信任的输入注入原始 HTML 输出,使攻击者可以执行恶意脚本或恶意修改网页中的内容。 |
CA3003:查看文件路径注入漏洞的代码 | 在处理来自 Web 请求的不受信任的输入时,请谨慎使用用户控制的输入指定文件路径。 |
CA3004:查看信息泄露漏洞的代码 | 泄漏异常信息可让攻击者深入了解应用程序的内部机制,从而帮助攻击者找到其他漏洞并利用这些漏洞。 |
CA3005:查看 LDAP 注入漏洞的代码 | 使用不受信任的输入时,请注意防范轻型目录访问协议 (LDAP) 注入攻击。 攻击者可能会对信息目录运行恶意 LDAP 语句。 使用用户输入构造动态 LDAP 语句来访问目录服务的应用程序尤其容易受到攻击。 |
CA3006:查看进程命令注入漏洞的代码 | 处理不受信任的输入时,请注意防范命令注入攻击。 命令注入攻击可在基础操作系统上执行恶意命令,从而降低服务器的安全和完整性。 |
CA3007:查看公开重定向漏洞的代码 | 处理不受信任的输入时,请注意防范开放重定向漏洞。 攻击者可以利用开放重定向漏洞,使用你的网站提供合法 URL 的外观,但将毫不知情的访客重定向到钓鱼网页或其他恶意网页。 |
CA3008:查看 XPath 注入漏洞的代码 | 处理不受信任的输入时,请注意防范 XPath 注入攻击。 使用不受信任的输入构造 XPath 查询可能会使攻击者恶意操纵查询以返回意外结果,并可能披露查询 XML 的内容。 |
CA3009:查看 XML 注入漏洞的代码 | 处理不受信任的输入时,请注意防范 XML 注入攻击。 |
CA3010:查看 XAML 注入漏洞的代码 | 处理不受信任的输入时,请注意防范 XAML 注入攻击。 XAML 是一种直接表示对象实例化和执行的标记语言。 这意味着 XAML 中创建的元素可以与系统资源(例如,网络访问和文件系统 IO)交互。 |
CA3011:查看 DLL 注入漏洞的代码 | 处理不受信任的输入时,请谨慎加载不受信任的代码。 如果 Web 应用程序加载不受信任的代码,攻击者可能会将恶意 DLL 注入进程并执行恶意代码。 |
CA3012:查看正则表达式注入漏洞的代码 | 处理不受信任的输入时,请注意防范正则表达式注入攻击。 攻击者可以使用正则表达式注入恶意修改正则表达式,让正则表达式匹配非预期结果,或者让正则表达式占用过多 CPU,从而形成拒绝服务攻击。 |
CA3061:请勿按 URL 添加架构 | 请勿使用 Add 方法的不安全重载,因为它可能会导致危险的外部引用。 |
CA3075:不安全的 DTD 处理 | 如果使用不安全的 DTDProcessing 实例或引用外部实体源,分析器可能会接受不受信任的输入并向攻击者披露敏感信息。 |
CA3076:不安全的 XSLT 脚本执行 | 如果不安全地在 .NET 应用程序中执行可扩展样式表语言转换(XSLT),处理器可能会解决不受信任的 URI 引用,这些引用可能会向攻击者披露敏感信息,从而导致拒绝服务和跨站点攻击。 |
CA3077:API 设计、XML 文档和 XML 文本读取器中的不安全处理 | 当设计派生自 XMLDocument 和 XMLTextReader 的 API 时,请注意 DtdProcessing。 在引用或解析外部实体源或设置 XML 中的不安全值时使用不安全的 DTDProcessing 实例可能会导致信息泄露。 |
CA3147:使用 ValidateAntiForgeryToken 标记谓词处理程序 | 设计 ASP.NET MVC 控制器时,请注意防范跨网站请求伪造攻击。 跨网站请求伪造攻击可将来自经过身份验证的用户的恶意请求发送到 ASP.NET MVC 控制器。 |
CA5350:请勿使用弱加密算法 | 出于多种原因,现今使用弱加密算法和哈希函数,但不应使用它们来保证保密性或它们所保护的数据的完整性。 当此规则在代码中找到 TripleDES、SHA1、或 RIPEMD160 算法时,此规则将触发。 |
CA5351:请勿使用已损坏的加密算法 | 损坏的加密算法不安全,强烈建议不要使用。 当此规则在代码中找到 MD5 哈希算法,或者 DES 或 RC2 加密算法时,此规则将触发。 |
CA5358:请勿使用不安全的密码模式 | 请勿使用不安全的密码模式 |
CA5359:请勿禁用证书验证 | 证书有助于对服务器的身份进行验证。 客户端应验证服务器证书,确保将请求发送到目标服务器。 如果 ServerCertificateValidationCallback 始终返回 true ,那么任何证书都将通过验证。 |
CA5360:在反序列化中不要调用危险的方法 | 不安全的反序列化是一种漏洞。当使用不受信任的数据来损害应用程序的逻辑,造成拒绝服务 (DoS) 攻击,或甚至在反序列化时任意执行代码,就会出现该漏洞。 应用程序对受其控制的不受信任数据进行反序列化时,恶意用户很可能会滥用这些反序列化功能。 具体来说,就是在反序列化过程中调用危险方法。 如果攻击者成功执行不安全的反序列化攻击,就能实施更多攻击,如 DoS 攻击、绕过身份验证和执行远程代码。 |
CA5361:不禁用强加密的 SChannel 使用 | 将 Switch.System.Net.DontEnableSchUseStrongCrypto 设置为 true 会减弱传出的传输层安全性连接中使用的加密性。 较弱的加密性会泄露应用程序与服务器之间通信的机密性,使攻击者更易于窃听敏感数据。 |
CA5362:反序列化对象图中存在潜在引用循环 | 反序列化不受信任的数据时,处理反序列化对象图的任何代码都需要在处理引用循环时不进入无限循环。 这包括反序列化回叫中的一部分代码和在反序列化完成后处理对象图的代码。 否则攻击者可能会利用带有包含引用循环的恶意数据执行拒绝服务攻击。 |
CA5363:请勿禁用请求验证 | 请求验证是 ASP.NET 中的一项功能,可检查 HTTP 请求并确定这些请求是否包含可能导致跨站点脚本编写等注入攻击的潜在危险内容。 |
CA5364:不使用已弃用的安全协议 | 传输层安全性 (TLS) 通常使用超文本传输协议安全 (HTTPS) 保障计算机之间的通信安全。 早期版本的 TLS 协议不如 TLS 1.2 和 TLS 1.3 安全,且更容易出现新的漏洞。 避免使用旧版本的协议,以便最大程度降低风险。 |
CA5365:请勿禁用 HTTP 头检查 | 通过 HTTP 标头检查,可对在响应头中找到的回车符和换行符(\r 和 \n)进行编码。 此编码有助于避免注入攻击,这些注入攻击会攻击对标头包含的不受信数据进行回显的应用程序。 |
CA5366:将 XmlReader 用于数据集读取 XML | DataSet使用不受信任的数据读取 XML 可能会加载危险的外部引用,这应该通过使用XmlReader具有安全解析程序或禁用 DTD 处理来限制这些引用。 |
CA5367:请勿序列化具有 Pointer 字段的类型 | 此规则检查是否存在带有指针字段或属性的可序列化类。 无法进行序列化的成员可能是指针,例如使用 NonSerializedAttribute 进行标记的静态成员或字段。 |
CA5368:针对派生自 Page 的类设置 ViewStateUserKey | 设置 ViewStateUserKey 属性有助于防止对应用程序的攻击,方法是允许你为各个用户的视图状态变量分配标识符,这样攻击者就无法使用变量生成攻击。 否则会出现“跨网站请求伪造”漏洞。 |
CA5369:将 XmlReader 用于反序列化 | 处理不受信任的 DTD 和 XML 架构可能会启用加载危险的外部引用,应通过使用具有安全解析程序的 XmlReader 或禁用 DTD 和 XML 内联架构处理来限制这些引用。 |
CA5370:将 XmlReader 用于验证读取器 | 处理不受信任的 DTD 和 XML 架构可能会启用加载危险的外部引用。 此危险的加载行为可使用具有安全解析程序或者禁用了 DTD 和 XML 内联架构处理的 XmlReader 来进行限制。 |
CA5371:将 XmlReader 用于架构读取 | 处理不受信任的 DTD 和 XML 架构可能会启用加载危险的外部引用。 请使用具有安全解析程序或者禁用了 DTD 和 XML 内联架构处理的 XmlReader 对其进行限制。 |
CA5372:将 XmlReader 用于 XPathDocument | 处理来自不受信任的数据的 XML 可能会加载危险的外部引用,这可以通过使用具有安全解析程序的 XmlReader 或禁用 DTD 处理来限制这些引用。 |
CA5373:请勿使用已过时的密钥派生功能 | 此规则会检测对弱密钥派生方法 System.Security.Cryptography.PasswordDeriveBytes 和 Rfc2898DeriveBytes.CryptDeriveKey 的调用。 System.Security.Cryptography.PasswordDeriveBytes 使用了弱算法 PBKDF1。 |
CA5374:请勿使用 XslTransform | 此规则检查 System.Xml.Xsl.XslTransform 是否在代码中进行了实例化。 System.Xml.Xsl.XslTransform 现已过时且不应使用。 |
CA5375:请勿使用帐户共享访问签名 | 帐户 SAS 可以委派对 blob 容器、表、队列和文件共享执行读取、写入和删除操作的访问权限,而这是服务 SAS 所不允许的。 但是它不支持容器级别的策略,并且其灵活性和对授予的权限的控制力更低。 一旦恶意用户获取它后,存储帐户的信息很容易泄露。 |
CA5376:使用 SharedAccessProtocol HttpsOnly | SAS 是无法在 HTTP 上以纯文本形式传输的敏感数据。 |
CA5377:使用容器级别访问策略 | 容器级别的访问策略可以随时修改或撤销。 它具有更高的灵活性,对授予的权限的控制力更强。 |
CA5378:不禁用 ServicePointManagerSecurityProtocols | 将 Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols 设置为 true 会将 Windows Communication Framework (WCF) 的传输层安全性 (TLS) 连接限制为使用 TLS 1.0。 该版本的 TLS 将被弃用。 |
CA5379:不使用弱键派生函数算法 | Rfc2898DeriveBytes 类默认使用 SHA1 算法。 应指定在 SHA256 或更高版本的构造函数的某些重载中使用哈希算法。 请注意,HashAlgorithm 属性只具有 get 访问器,而没有 overridden 修饰符。 |
CA5380:请勿将证书添加到根存储中 | 此规则会对将证书添加到“受信任的根证书颁发机构”证书存储的代码进行检测。 默认情况下,“受信任的根证书颁发机构”证书存储配置有一组符合 Microsoft 根证书计划要求的公共 CA。 |
CA5381:请确保证书未添加到根存储中 | 此规则会对可能将证书添加到“受信任的根证书颁发机构”证书存储的代码进行检测。 默认情况下,“受信任的根证书颁发机构”证书存储配置有一组符合 Microsoft 根证书计划要求的公共证书颁发机构 (CA)。 |
CA5382:在 ASP.NET Core 中使用安全 Cookie | HTTPS 上可用的应用程序必须使用安全 Cookie,这会向浏览器指示,Cookie 只能使用安全套接字层 (SSL) 进行传输。 |
CA5383:确保在 ASP.NET Core 中使用安全 Cookie | HTTPS 上可用的应用程序必须使用安全 Cookie,这会向浏览器指示,Cookie 只能使用安全套接字层 (SSL) 进行传输。 |
CA5384:不使用数字签名算法(DSA) | DSA 是一种弱非对称加密算法。 |
CA5385:设置具有足够密钥大小的 Rivest–Shamir–Adleman (RSA)算法 | 小于 2048 位的 RSA 密钥更容易受到暴力攻击。 |
CA5386:避免对 SecurityProtocolType 值进行硬编码 | 传输层安全性 (TLS) 通常使用安全超文本传输协议 (HTTPS) 保障计算机之间的通信安全。 协议版本 TLS 1.0 和 TLS 1.1 已弃用,目前使用 TLS 1.2 和 TLS 1.3。 将来,可能会弃用 TLS 1.2 和 TLS 1.3。 要确保应用程序的安全性,请避免对协议版本进行硬编码,并且至少以 .NET Framework v4.7.1 为目标。 |
CA5387:请勿使用迭代计数不足的弱密钥派生功能 | 此规则检查加密密钥是否由迭代计数小于 100,000 的 Rfc2898DeriveBytes 生成。 迭代计数较高有助于缓解尝试猜测已生成的加密密钥的字典攻击。 |
CA5388:使用弱密钥派生功能时,请确保迭代计数足够大 | 此规则检查是否使用 Rfc2898DeriveBytes 迭代计数生成的加密密钥可能小于 100,000。 迭代计数较高有助于缓解尝试猜测已生成的加密密钥的字典攻击。 |
CA5389:请勿将存档项的路径添加到目标文件系统路径中 | 文件路径可以是相对的,并且可能导致文件系统访问预期文件系统目标路径以外的内容,从而导致攻击者通过“布局和等待”技术恶意更改配置和执行远程代码。 |
CA5390:请勿编码加密密钥 | 要成功使用对称算法,密钥必须只有发送方和接收方知道。 如果密钥是硬编码的,就容易被发现。 即使使用编译的二进制文件,恶意用户也容易将其提取出来。 私钥泄露后,密码文本可直接被解密并且不再受保护。 |
CA5391:在 ASP.NET Core MVC 控制器中使用防伪造令牌 | POST 在未验证反伪造令牌的情况下处理、PUT PATCH 或DELETE 请求可能会容易受到跨站点请求伪造攻击。 跨网站请求伪造攻击可将经过身份验证的用户的恶意请求发送到 ASP.NET Core MVC 控制器。 |
CA5392:对 P/Invoke 使用 DefaultDllImportSearchPaths 属性 | 默认情况下,使用 DllImportAttribute 的 P/Invoke 函数会探测大量目录,包括要加载的库的当前工作目录。 这对于某些应用程序来说是一个安全隐患,会导致 DLL 劫持。 |
CA5393:请勿使用不安全的 DllImportSearchPath 值 | 默认的 DLL 搜索目录和程序集目录中可能存在恶意 DLL。 或者根据应用程序运行的位置,应用程序的目录中可能存在恶意 DLL。 |
CA5394:请勿使用不安全的随机性 | 使用加密弱伪随机数生成器可能会让攻击者预测将生成哪些安全敏感值。 |
CA5395:缺少操作方法的 HttpVerb 属性 | 创建、编辑或以其它方式修改数据等所有操作方法都需要使用防伪特性来保护,以避免受跨网站请求伪造攻击的影响。 执行 GET 操作应是没有副作用且不会修改持久数据的安全操作。 |
CA5396:将 HttpCookie 的 HttpOnly 设置为 true | 请确保将安全敏感的 HTTP Cookie 标记为 HttpOnly,这是一个深度防御措施。 这表明 Web 浏览器应禁止脚本访问 Cookie。 注入恶意脚本是常见的窃取 Cookie 的方式。 |
CA5397:不使用已弃用的 SslProtocols 值 | 传输层安全性 (TLS) 通常使用安全超文本传输协议 (HTTPS) 保障计算机之间的通信安全。 早期版本的 TLS 协议不如 TLS 1.2 和 TLS 1.3 安全,且更容易出现新的漏洞。 避免使用旧版本的协议,以便最大程度降低风险。 |
CA5398:避免硬编码的 SslProtocols 值 | 传输层安全性 (TLS) 通常使用安全超文本传输协议 (HTTPS) 保障计算机之间的通信安全。 协议版本 TLS 1.0 和 TLS 1.1 已弃用,目前使用 TLS 1.2 和 TLS 1.3。 将来,可能会弃用 TLS 1.2 和 TLS 1.3。 要确保应用程序的安全性,请避免对协议版本进行硬编码。 |
CA5399:绝对禁用 HttpClient 证书吊销列表检查 | 撤销的证书不再受信任。 攻击者可能使用它来传递某些恶意数据或窃取 HTTPS 通信中的敏感数据。 |
CA5400:确保未禁用 HttpClient 证书吊销列表检查 | 撤销的证书不再受信任。 攻击者可能使用它来传递某些恶意数据或窃取 HTTPS 通信中的敏感数据。 |
CA5401:不要将 CreateEncryptor 与非默认 IV 结合使用 | 对称加密应始终使用非可重复的初始化向量,以防止字典攻击。 |
CA5402:将 CreateEncryptor 与默认 IV 结合使用 | 对称加密应始终使用非可重复的初始化向量,以防止字典攻击。 |
CA5403:请勿硬编码证书 | X509Certificate 或 X509Certificate2 构造函数的 data 或 rawData 参数是硬编码的。 |
CA5404:不要禁用令牌验证检查 | 用于控制令牌验证的 TokenValidationParameters 属性不应设置为 false 。 |
CA5405:不要始终跳过委托中的令牌验证 | 分配给 AudienceValidator 或 LifetimeValidator 的回调始终返回 true 。 |
IL3000:避免在发布为单个文件时访问程序集文件路径 | 当发布为单个文件时,避免访问程序集文件路径。 |
IL3001:避免在以单文件的形式发布时访问程序集文件路径 | 当发布为单个文件时,避免访问程序集文件路径。 |
IL3002:在发布为单个文件时避免调用使用“RequiresAssemblyFilesAttribute”批注的成员 | 当发布为单个文件时,避免调用使用“RequiresAssemblyFilesAttribute”批注的成员 |
IL3003:“RequiresAssemblyFilesAttribute”批注必须在所有接口实现或重写之间匹配。 | “RequiresAssemblyFilesAttribute”批注在所有接口实现或替代中必须匹配。 |
图例
下表显示了为参考文档中每个规则提供的信息类型。
项 | 描述 |
---|---|
类型 | 规则的 TypeName。 |
规则 ID | 规则的唯一标识符。 RuleId 和类别用于源代码中禁止显示警告。 |
类别 | 规则的类别,例如安全性。 |
修复是中断修复还是非中断修复 | 规则冲突的修复是否是一项重大更改。 重大更改意味着,在导致冲突的目标上具有依赖关系的程序集不会使用新修复的版本重新编译,或者可能会由于此更改在运行时失败。 当具有多个修复可用且至少有一个修复是一项重大更改,有一个不是时,将同时指定“重大”和“非重大”。 |
原因 | 导致规则生成警告的特定托管代码。 |
说明 | 讨论警告背后的问题。 |
如何解决冲突 | 说明如何更改源代码以满足规则并防止它生成警告。 |
何时禁止显示警告 | 描述何时可以安全地禁止显示此规则警告。 |
示例代码 | 规则冲突示例和满足该规则的已更正示例。 |
相关规则 | 相关规则。 |