From dff6e83867d6f7835975c0076290db8f36ed0dc5 Mon Sep 17 00:00:00 2001 From: Fredi Kats Date: Sat, 18 May 2024 23:13:11 +0200 Subject: [PATCH] Add possibility to execute commands without cloned MS Learn repository --- .../Kysect.Configuin.ConfigurationRoot.csproj | 3 ++ .../roslyn-rules.json | 1 + .../Commands/AnalyzeEditorConfigCommand.cs | 6 ++-- .../Commands/FormatEditorconfigCommand.cs | 5 +-- .../Commands/GenerateCodeStyleDocCommand.cs | 5 +-- .../GenerateEditorConfigTemplateTemplate.cs | 6 ++-- .../GenerateRoslynRuleDocumentationFile.cs | 36 +++++++++++++++++++ Sources/Kysect.Configuin.Console/Program.cs | 4 ++- .../RoslynRuleDocumentationCache.cs | 21 +++++++++++ .../Analyzing/EditorConfigAnalyzer.cs | 4 +-- .../LearnDocumentationParser.cs | 2 +- .../RoslynRules.cs | 17 +++------ .../RoslynStyleRuleGroup.cs | 20 +---------- .../WellKnownRoslynRuleDefinitions.cs | 5 +-- 14 files changed, 90 insertions(+), 45 deletions(-) create mode 100644 Sources/Kysect.Configuin.ConfigurationRoot/roslyn-rules.json create mode 100644 Sources/Kysect.Configuin.Console/Commands/GenerateRoslynRuleDocumentationFile.cs create mode 100644 Sources/Kysect.Configuin.Console/RoslynRuleDocumentationCache.cs diff --git a/Sources/Kysect.Configuin.ConfigurationRoot/Kysect.Configuin.ConfigurationRoot.csproj b/Sources/Kysect.Configuin.ConfigurationRoot/Kysect.Configuin.ConfigurationRoot.csproj index ea7520d..613a2c2 100644 --- a/Sources/Kysect.Configuin.ConfigurationRoot/Kysect.Configuin.ConfigurationRoot.csproj +++ b/Sources/Kysect.Configuin.ConfigurationRoot/Kysect.Configuin.ConfigurationRoot.csproj @@ -26,6 +26,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Sources/Kysect.Configuin.ConfigurationRoot/roslyn-rules.json b/Sources/Kysect.Configuin.ConfigurationRoot/roslyn-rules.json new file mode 100644 index 0000000..8104705 --- /dev/null +++ b/Sources/Kysect.Configuin.ConfigurationRoot/roslyn-rules.json @@ -0,0 +1 @@ +{"QualityRules":[{"RuleId":{"RuleType":"CA","Id":1000},"Title":"Do not declare static members on generic types","Category":"Design","Description":"When a static member of a generic type is called, the type argument must be specified for the type. When a generic instance member that does not support inference is called, the type argument must be specified for the member. The syntax for specifying the type argument in these two cases is different and easily confused, as the following calls demonstrate:\r\n\u0027 Shared method in a generic type.\r\nGenericType(Of Integer).SharedMethod()\r\n\r\n\u0027 Generic instance method that does not support inference.\r\nsomeObject.GenericMethod(Of Integer)()\r\n// Static method in a generic type.\r\nGenericType\u003Cint\u003E.StaticMethod();\r\n\r\n// Generic instance method that does not support inference.\r\nsomeObject.GenericMethod\u003Cint\u003E();\r\nGenerally, both of the prior declarations should be avoided so that the type argument does not have to be specified when the member is called. This results in a syntax for calling members in generics that is no different from the syntax for non-generics.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1001},"Title":"Types that own disposable fields should be disposable","Category":"Design","Description":"A class that declares an System.IDisposable field indirectly owns an unmanaged resource. The class should implement the System.IDisposable interface to dispose of the unmanaged resource that it owns once the resource is no longer in use. If the class does not directly own any unmanaged resources, it should not implement a finalizer.\r\nThis rule respects types implementing System.IAsyncDisposable as disposable types.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1002},"Title":"Do not expose generic lists","Category":"Design","Description":"System.Collections.Generic.List%601 is a generic collection that\u0027s designed for performance and not inheritance. System.Collections.Generic.List%601 does not contain virtual members that make it easier to change the behavior of an inherited class. The following generic collections are designed for inheritance and should be exposed instead of System.Collections.Generic.List%601.\r\nSystem.Collections.ObjectModel.Collection%601\r\n System.Collections.ObjectModel.ReadOnlyCollection%601\r\n System.Collections.ObjectModel.KeyedCollection%602\r\n System.Collections.Generic.IList%601\r\n System.Collections.Generic.ICollection%601","Options":[]},{"RuleId":{"RuleType":"CA","Id":1003},"Title":"Use generic event handler instances","Category":"Design","Description":"Before .NET Framework 2.0, in order to pass custom information to the event handler, a new delegate had to be declared that specified a class that was derived from the System.EventArgs class. In .NET Framework 2.0 and later versions, the generic System.EventHandler%601 delegate allows any class that\u0027s derived from System.EventArgs to be used together with the event handler.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1005},"Title":"Avoid excessive parameters on generic types","Category":"Design","Description":"The more type parameters a generic type contains, the more difficult it is to know and remember what each type parameter represents. It is usually obvious with one type parameter, as in List\u003CT\u003E, and in certain cases with two type parameters, as in Dictionary\u003CTKey, TValue\u003E. If more than two type parameters exist, the difficulty becomes too great for most users (for example, TooManyTypeParameters\u003CT, K, V\u003E in C# or TooManyTypeParameters(Of T, K, V) in Visual Basic).","Options":[]},{"RuleId":{"RuleType":"CA","Id":1008},"Title":"Enums should have zero value","Category":"Design","Description":"The default value of an uninitialized enumeration, just like other value types, is zero. A non-flags-attributed enumeration should define a member that has the value of zero so that the default value is a valid value of the enumeration. If appropriate, name the member \u0027None\u0027 (or one of the additional permitted names). Otherwise, assign zero to the most frequently used member. By default, if the value of the first enumeration member is not set in the declaration, its value is zero.\r\nIf an enumeration that has the System.FlagsAttribute applied defines a zero-valued member, its name should be \u0027None\u0027 (or one of the additional permitted names) to indicate that no values have been set in the enumeration. Using a zero-valued member for any other purpose is contrary to the use of the System.FlagsAttribute in that the AND and OR bitwise operators are useless with the member. This implies that only one member should be assigned the value zero. If multiple members that have the value zero occur in a flags-attributed enumeration, Enum.ToString() returns incorrect results for members that are not zero.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1010},"Title":"Collections should implement generic interface","Category":"Design","Description":"To broaden the usability of a collection, implement one of the generic collection interfaces. Then the collection can be used to populate generic collection types such as the following:\r\nSystem.Collections.Generic.List%601\r\n System.Collections.Generic.Queue%601\r\n System.Collections.Generic.Stack%601","Options":[]},{"RuleId":{"RuleType":"CA","Id":1012},"Title":"Abstract types should not have public constructors","Category":"Design","Description":"Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1014},"Title":"Mark assemblies with CLSCompliantAttribute","Category":"Design","Description":"The Common Language Specification (CLS) defines naming restrictions, data types, and rules to which assemblies must conform if they will be used across programming languages. Good design dictates that all assemblies explicitly indicate CLS compliance with System.CLSCompliantAttribute. If the attribute is not present on an assembly, the assembly is not compliant.\r\nIt is possible for a CLS-compliant assembly to contain types or type members that are not compliant.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1016},"Title":"Mark assemblies with AssemblyVersionAttribute","Category":"Design","Description":"The identity of an assembly is composed of the following information:\r\nAssembly name\r\n Version number\r\n Culture\r\n Public key (for strongly named assemblies).\r\n.NET uses the version number to uniquely identify an assembly and to bind to types in strongly named assemblies. The version number is used together with version and publisher policy. By default, applications run only with the assembly version with which they were built.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1017},"Title":"Mark assemblies with ComVisibleAttribute","Category":"Design","Description":"The System.Runtime.InteropServices.ComVisibleAttribute attribute determines how COM clients access managed code. Good design dictates that assemblies explicitly indicate COM visibility. COM visibility can be set for a whole assembly and then overridden for individual types and type members. If the attribute is not present, the contents of the assembly are visible to COM clients.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1018},"Title":"Mark attributes with AttributeUsageAttribute","Category":"Design","Description":"When you define a custom attribute, mark it by using System.AttributeUsageAttribute to indicate where in the source code the custom attribute can be applied. The meaning and intended usage of an attribute will determine its valid locations in code. For example, you might define an attribute that identifies the person who is responsible for maintaining and enhancing each type in a library, and that responsibility is always assigned at the type level. In this case, compilers should enable the attribute on classes, enumerations, and interfaces, but should not enable it on methods, events, or properties. Organizational policies and procedures would dictate whether the attribute should be enabled on assemblies.\r\nThe System.AttributeTargets enumeration defines the targets that you can specify for a custom attribute. If you omit System.AttributeUsageAttribute, your custom attribute will be valid for all targets, as defined by the All value of System.AttributeTargets enumeration.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1019},"Title":"Define accessors for attribute arguments","Category":"Design","Description":"Attributes can define mandatory arguments that must be specified when you apply the attribute to a target. These are also known as positional arguments because they are supplied to attribute constructors as positional parameters. For every mandatory argument, the attribute should also provide a corresponding read-only property so that the value of the argument can be retrieved at execution time. This rule checks that for each constructor parameter, you have defined the corresponding property.\r\nAttributes can also define optional arguments, which are also known as named arguments. These arguments are supplied to attribute constructors by name and should have a corresponding read/write property.\r\nFor mandatory and optional arguments, the corresponding properties and constructor parameters should use the same name but different casing. Properties use Pascal casing, and parameters use camel casing.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1021},"Title":"Avoid out parameters","Category":"Design","Description":"Passing types by reference (using out or ref) requires experience with pointers, understanding how value types and reference types differ, and handling methods with multiple return values. Also, the difference between out and ref parameters is not widely understood.\r\nWhen a reference type is passed \u0022by reference,\u0022 the method intends to use the parameter to return a different instance of the object. Passing a reference type by reference is also known as using a double pointer, pointer to a pointer, or double indirection. By using the default calling convention, which is pass \u0022by value,\u0022 a parameter that takes a reference type already receives a pointer to the object. The pointer, not the object to which it points, is passed by value. Pass by value means that the method cannot change the pointer to have it point to a new instance of the reference type. However, it can change the contents of the object to which it points. For most applications this is sufficient and yields the desired behavior.\r\nIf a method must return a different instance, use the return value of the method to accomplish this. See the System.String class for a variety of methods that operate on strings and return a new instance of a string. When this model is used, the caller must decide whether the original object is preserved.\r\nAlthough return values are commonplace and heavily used, the correct application of out and ref parameters requires intermediate design and coding skills. Library architects who design for a general audience should not expect users to become proficient in working with out or ref parameters.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1024},"Title":"Use properties where appropriate","Category":"Design","Description":"In most cases, properties represent data and methods perform actions. Properties are accessed like fields, which makes them easier to use. A method is a good candidate to become a property if one of these conditions is present:\r\nThe method takes no arguments and returns the state information of an object.\r\n The method accepts a single argument to set some part of the state of an object.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1027},"Title":"Mark enums with FlagsAttribute","Category":"Design","Description":"An enumeration is a value type that defines a set of related named constants. Apply System.FlagsAttribute to an enumeration when its named constants can be meaningfully combined. For example, consider an enumeration of the days of the week in an application that keeps track of which day\u0027s resources are available. If the availability of each resource is encoded by using the enumeration that has System.FlagsAttribute present, any combination of days can be represented. Without the attribute, only one day of the week can be represented.\r\nFor fields that store combinable enumerations, the individual enumeration values are treated as groups of bits in the field. Therefore, such fields are sometimes referred to as bit fields. To combine enumeration values for storage in a bit field, use the Boolean conditional operators. To test a bit field to determine whether a specific enumeration value is present, use the Boolean logical operators. For a bit field to store and retrieve combined enumeration values correctly, each value that is defined in the enumeration must be a power of two. Unless this is so, the Boolean logical operators will not be able to extract the individual enumeration values that are stored in the field.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1028},"Title":"Enum storage should be Int32","Category":"Design","Description":"An enumeration is a value type that defines a set of related named constants. By default, the System.Int32 data type is used to store the constant value. Even though you can change this underlying type, it is not necessary or recommended for most scenarios. No significant performance gain is achieved by using a data type that is smaller than System.Int32. If you cannot use the default data type, you should use one of the Common Language System (CLS)-compliant integral types, System.Byte, System.Int16, System.Int32, or System.Int64 to make sure that all values of the enumeration can be represented in CLS-compliant programming languages.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1030},"Title":"Use events where appropriate","Category":"Design","Description":"This rule detects methods that have names that ordinarily would be used for events. Events follow the Observer or Publish-Subscribe design pattern; they are used when a state change in one object must be communicated to other objects. If a method gets called in response to a clearly defined state change, the method should be invoked by an event handler. Objects that call the method should raise events instead of calling the method directly.\r\nSome common examples of events are found in user interface applications where a user action such as clicking a button causes a segment of code to execute. The .NET event model is not limited to user interfaces. It should be used anywhere you must communicate state changes to one or more objects.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1031},"Title":"Do not catch general exception types","Category":"Design","Description":"General exceptions should not be caught.","Options":["disallowed_symbol_names"]},{"RuleId":{"RuleType":"CA","Id":1032},"Title":"Implement standard exception constructors","Category":"Design","Description":"Exception types must implement the following three public constructors:\r\npublic NewException()\r\n public NewException(string)\r\n public NewException(string, Exception)\r\nFailure to provide the full set of constructors can make it difficult to correctly handle exceptions. For example, the constructor that has the signature NewException(string, Exception) is used to create exceptions that are caused by other exceptions. Without this constructor, you can\u0027t create and throw an instance of your custom exception that contains an inner (nested) exception, which is what managed code should do in such a situation.\r\nFor more information, see CA2229: Implement serialization constructors.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1033},"Title":"Interface methods should be callable by child types","Category":"Design","Description":"Consider a base type that explicitly implements a public interface method. A type that derives from the base type can access the inherited interface method only through a reference to the current instance (this in C#) that is cast to the interface. If the derived type reimplements (explicitly) the inherited interface method, the base implementation can no longer be accessed. The call through the current instance reference will invoke the derived implementation; this causes recursion and an eventual stack overflow.\r\nThis rule does not report a violation for an explicit implementation of System.IDisposable.Dispose when an externally visible Close() or System.IDisposable.Dispose(Boolean) method is provided.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1034},"Title":"Nested types should not be visible","Category":"Design","Description":"A nested type is a type declared within the scope of another type. Nested types are useful for encapsulating private implementation details of the containing type. Used for this purpose, nested types should not be externally visible.\r\nDo not use externally visible nested types for logical grouping or to avoid name collisions; instead, use namespaces.\r\nNested types include the notion of member accessibility, which some programmers do not understand clearly.\r\nProtected types can be used in subclasses and nested types in advance customization scenarios.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1036},"Title":"Override methods on comparable types","Category":"Design","Description":"Types that define a custom sort order implement the System.IComparable interface. The System.IComparable.CompareTo%2A method returns an integer value that indicates the correct sort order for two instances of the type. This rule identifies types that set a sort order. Setting a sort order implies that the ordinary meaning of equality, inequality, less-than, and greater-than don\u0027t apply. When you provide an implementation of System.IComparable, you must usually also override System.Object.Equals%2A so that it returns values that are consistent with System.IComparable.CompareTo%2A. If you override System.Object.Equals%2A and are coding in a language that supports operator overloads, you should also provide operators that are consistent with System.Object.Equals%2A.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1040},"Title":"Avoid empty interfaces","Category":"Design","Description":"Interfaces define members that provide a behavior or usage contract. The functionality that is described by the interface can be adopted by any type, regardless of where the type appears in the inheritance hierarchy. A type implements an interface by providing implementations for the members of the interface. An empty interface does not define any members. Therefore, it does not define a contract that can be implemented.\r\nIf your design includes empty interfaces that types are expected to implement, you are probably using an interface as a marker or a way to identify a group of types. If this identification will occur at run time, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the properties of the attribute, to identify the target types. If the identification must occur at compile time, then it is acceptable to use an empty interface.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1041},"Title":"Provide ObsoleteAttribute message","Category":"Design","Description":"System.ObsoleteAttribute is used to mark deprecated library types and members. Library consumers should avoid the use of any type or member that is marked obsolete. This is because it might not be supported and will eventually be removed from later versions of the library. When a type or member marked by using System.ObsoleteAttribute is compiled, the System.ObsoleteAttribute.Message%2A property of the attribute is displayed. This gives the user information about the obsolete type or member. This information generally includes how long the obsolete type or member will be supported by the library designers and the preferred replacement to use.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1043},"Title":"Use integral or string argument for indexers","Category":"Design","Description":"Indexers, that is, indexed properties, should use integer or string types for the index. These types are typically used for indexing data structures and increase the usability of the library. Use of the System.Object type should be restricted to those cases where the specific integer or string type cannot be specified at design time. If the design requires other types for the index, reconsider whether the type represents a logical data store. If it does not represent a logical data store, use a method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1044},"Title":"Properties should not be write only","Category":"Design","Description":"Get accessors provide read access to a property and set accessors provide write access. Although it is acceptable and often necessary to have a read-only property, the design guidelines prohibit the use of write-only properties. This is because letting a user set a value and then preventing the user from viewing the value does not provide any security. Also, without read access, the state of shared objects cannot be viewed, which limits their usefulness.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1045},"Title":"Do not pass types by reference","Category":"Design","Description":"Passing types by reference (using out or ref) requires experience with pointers, understanding how value types and reference types differ, and handling methods that have multiple return values. Also, the difference between out and ref parameters is not widely understood.\r\nWhen a reference type is passed \u0022by reference,\u0022 the method intends to use the parameter to return a different instance of the object. (Passing a reference type by reference is also known as using a double pointer, pointer to a pointer, or double indirection.) Using the default calling convention, which is pass \u0022by value,\u0022 a parameter that takes a reference type already receives a pointer to the object. The pointer, not the object to which it points, is passed by value. Passing by value means that the method cannot change the pointer to have it point to a new instance of the reference type, but can change the contents of the object to which it points. For most applications this is sufficient and yields the behavior that you want.\r\nIf a method must return a different instance, use the return value of the method to accomplish this. See the System.String class for a variety of methods that operate on strings and return a new instance of a string. By using this model, it is left to the caller to decide whether the original object is preserved.\r\nAlthough return values are commonplace and heavily used, the correct application of out and ref parameters requires intermediate design and coding skills. Library architects who design for a general audience should not expect users to become proficient in working with out or ref parameters.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nWhen you work with parameters that are large structures, the additional resources that are required to copy these structures could cause a performance effect when you pass by value. In these cases, you might consider using ref or out parameters.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1046},"Title":"Do not overload operator equals on reference types","Category":"Design","Description":"For reference types, the default implementation of the equality operator is almost always correct. By default, two references are equal only if they point to the same object.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1047},"Title":"Do not declare protected members in sealed types","Category":"Design","Description":"Types declare protected members so that inheriting types can access or override the member. By definition, you cannot inherit from a sealed type, which means that protected methods on sealed types cannot be called.\r\nThe C# compiler emits warning CS0628 instead of CA1047 for this situation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1050},"Title":"Declare types in namespaces","Category":"Design","Description":"Types are declared in namespaces to prevent name collisions, and as a way to organize related types in an object hierarchy. Types that are outside any named namespace are in a global namespace that cannot be referenced in code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1051},"Title":"Do not declare visible instance fields","Category":"Design","Description":"The primary use of a field should be as an implementation detail. Fields should be private or internal and should be exposed by using properties. It\u0027s as easy to access a property as it is to access a field, and the code in the accessors of a property can change as the features of the type expand without introducing breaking changes.\r\nProperties that just return the value of a private or internal field are optimized to perform on par with accessing a field; the performance gain from using externally visible fields instead of properties is minimal. Externally visible refers to public, protected, and protected internal (Public, Protected, and Protected Friend in Visual Basic) accessibility levels.\r\nAdditionally, public fields cannot be protected by Link demands. (Link demands don\u0027t apply to .NET Core apps.)","Options":[]},{"RuleId":{"RuleType":"CA","Id":1052},"Title":"Static holder types should be Static or NotInheritable","Category":"Design","Description":"Rule CA1052 assumes that a type that contains only static members is not designed to be inherited, because the type does not provide any functionality that can be overridden in a derived type. A type that is not meant to be inherited should be marked with the static modifier in C# to prohibit its use as a base type. Additionally, its default constructor should be removed. In Visual Basic, the class should be converted to a module.\r\nThis rule does not fire for abstract classes or classes that have a base class. However, the rule does fire for classes that support an empty interface.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nIn the latest analyzer implementation of this rule, it also encompasses the functionality of rule CA1053.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1053},"Title":"Static holder types should not have default constructors","Category":"Design","Description":"The default constructor is unnecessary because calling static members does not require an instance of the type. Also, because the type does not have non-static members, creating an instance does not provide access to any of the type\u0027s members.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1054},"Title":"URI parameters should not be strings","Category":"Design","Description":"This rule splits the parameter name into tokens based on the camel casing convention and checks whether each token equals \u0022uri\u0022, \u0022Uri\u0022, \u0022urn\u0022, \u0022Urn\u0022, \u0022url\u0022, or \u0022Url\u0022. If there\u0027s a match, the rule assumes that the parameter represents a uniform resource identifier (URI). A string representation of a URI is prone to parsing and encoding errors, and can lead to security vulnerabilities. If a method takes a string representation of a URI, a corresponding overload should be provided that takes an instance of the System.Uri class, which provides these services in a safe and secure manner.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1055},"Title":"URI return values should not be strings","Category":"Design","Description":"This rule splits the method name into tokens based on the Pascal casing convention and checks whether each token equals \u0022uri\u0022, \u0022Uri\u0022, \u0022urn\u0022, \u0022Urn\u0022, \u0022url\u0022, or \u0022Url\u0022. If there\u0027s a match, the rule assumes that the method returns a uniform resource identifier (URI). A string representation of a URI is prone to parsing and encoding errors, and can lead to security vulnerabilities. The System.Uri class provides these services in a safe and secure manner.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1056},"Title":"URI properties should not be strings","Category":"Design","Description":"This rule splits the property name into tokens based on the Pascal casing convention and checks whether each token equals \u0022uri\u0022, \u0022Uri\u0022, \u0022urn\u0022, \u0022Urn\u0022, \u0022url\u0022, or \u0022Url\u0022. If there\u0027s a match, the rule assumes that the property represents a uniform resource identifier (URI). A string representation of a URI is prone to parsing and encoding errors, and can lead to security vulnerabilities. The System.Uri class provides these services in a safe and secure manner.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1058},"Title":"Types should not extend certain base types","Category":"Design","Description":"Exceptions should derive from System.Exception or one of its subclasses in the System namespace.\r\nDo not create a subclass of System.Xml.XmlDocument if you want to create an XML view of an underlying object model or data source.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1060},"Title":"Move P/Invokes to NativeMethods class","Category":"Design","Description":"Platform Invocation methods, such as those that are marked by using the System.Runtime.InteropServices.DllImportAttribute attribute, or methods that are defined by using the Declare keyword in Visual Basic, access unmanaged code. These methods should be in one of the following classes:\r\nNativeMethods - This class does not suppress stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute must not be applied to this class.) This class is for methods that can be used anywhere because a stack walk will be performed.\r\n SafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are safe for anyone to call. Callers of these methods are not required to perform a full security review to make sure that the usage is secure because the methods are harmless for any caller.\r\n UnsafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are potentially dangerous. Any caller of these methods must perform a full security review to make sure that the usage is secure because no stack walk will be performed.\r\nThese classes are declared as internal (Friend in Visual Basic) and declare a private constructor to prevent new instances from being created. The methods in these classes should be static and internal (Shared and Friend in Visual Basic).","Options":[]},{"RuleId":{"RuleType":"CA","Id":1061},"Title":"Do not hide base class methods","Category":"Design","Description":"A method in a base type is hidden by an identically named method in a derived type when the parameter signature of the derived method differs only by types that are more weakly derived than the corresponding types in the parameter signature of the base method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1062},"Title":"Validate arguments of public methods","Category":"Design","Description":"All reference arguments that are passed to externally visible methods should be checked against null. If appropriate, throw an System.ArgumentNullException when the argument is null.\r\nIf a method can be called from an unknown assembly because it is declared public or protected, you should validate all parameters of the method. If the method is designed to be called only by known assemblies, mark the method internal and apply the System.Runtime.CompilerServices.InternalsVisibleToAttribute attribute to the assembly that contains the method.","Options":["exclude_extension_method_this_parameter","null_check_validation_methods"]},{"RuleId":{"RuleType":"CA","Id":1063},"Title":"Implement IDisposable correctly","Category":"Design","Description":"All System.IDisposable types should implement the Dispose pattern correctly.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1064},"Title":"Exceptions should be public","Category":"Design","Description":"An internal exception is only visible inside its own internal scope. After the exception falls outside the internal scope, only the base exception can be used to catch the exception. If the internal exception is inherited from System.Exception, System.SystemException, or System.ApplicationException, the external code will not have sufficient information to know what to do with the exception.\r\nBut, if the code has a public exception that later is used as the base for an internal exception, it is reasonable to assume the code further out will be able to do something intelligent with the base exception. The public exception will have more information than what is provided by System.Exception, System.SystemException, or System.ApplicationException.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1065},"Title":"Do not raise exceptions in unexpected locations","Category":"Design","Description":"Methods that are not expected to throw exceptions can be categorized as follows:\r\nProperty get methods\r\n Event accessor methods\r\n Equals methods\r\n GetHashCode methods\r\n ToString methods\r\n Static constructors\r\n Finalizers\r\n Dispose methods\r\n Equality operators\r\n Implicit cast operators\r\nThe following sections discuss these method types.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1066},"Title":"Implement IEquatable when overriding Equals","Category":"Design","Description":"A value type overriding System.Object.Equals%2A method indicates that it supports comparing two instances of the type for value equality. Consider implementing the System.IEquatable%601 interface to support strongly typed tests for equality. This ensures that callers performing equality checks invoke the strongly typed System.IEquatable%601.Equals method and avoid boxing the argument, improving performance. For more information, see here.\r\nYour System.IEquatable%601.Equals implementation should return results that are consistent with System.Object.Equals%2A.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1067},"Title":"Override Equals when implementing IEquatable","Category":"Design","Description":"A type implementing System.IEquatable%601 interface indicates that it supports comparing two instances of the type for equality. You should also override the base class implementations of System.Object.Equals%2A and System.Object.GetHashCode methods so that their behavior is consistent with that of the System.IEquatable%601.Equals implementation. See here for more details.\r\nYour System.Object.Equals%2A implementation should return results that are consistent with System.IEquatable%601.Equals implementation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1068},"Title":"CancellationToken parameters must come last","Category":"Design","Description":"Methods that perform long running operations or asynchronous operations and are cancelable normally take a cancellation token parameter. Each cancellation token has a System.Threading.CancellationTokenSource that creates the token and uses it for cancelable computations. It is common practice to have a long chain of method calls that pass around the cancellation token from the callers to the callees. Hence, a large number of methods that take part in a cancelable computation end up having a cancellation token parameter. However, the cancellation token itself is not usually relevant to the core functionality of a majority of these methods. It\u0027s considered a good API design practice to have such parameters be the last parameter in the list.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1069},"Title":"Enums should not have duplicate values","Category":"Design","Description":"Every enum member should either have a unique constant value or be explicitly assigned with a prior member in the enum to indicate explicit intent of sharing value. For example:\r\nenum E\r\n{\r\n Field1 = 1,\r\n AnotherNameForField1 = Field1, // This is fine\r\n Field2 = 2,\r\n Field3 = 2, // CA1069: This is not fine. Either assign a different constant value or \u0027Field2\u0027 to indicate explicit intent of sharing value.\r\n}\r\nThis rule helps in catching functional bugs introduced from the following scenarios:\r\nAccidental typing mistakes, where the user accidentally typed the same constant value for multiple members.\r\n Copy paste mistakes, where the user copied an existing member definition, then renamed the member but forgot to change the value.\r\n Merge resolution from multiple branches, where a new member was added with a different name but the same value in different branches.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1070},"Title":"Do not declare event fields as virtual","Category":"Design","Description":"Follow these .NET design guidelines to raise base class events in derived classes. Do not declare virtual events in a base class. Overridden events in a derived class have undefined behavior. The C# compiler does not handle this correctly and it is unpredictable whether a subscriber to the derived event will actually be subscribing to the base class event.\r\nusing System;\r\npublic class C\r\n{\r\n // CA1070: Event \u0027ThresholdReached\u0027 should not be declared virtual.\r\n public virtual event EventHandler ThresholdReached;\r\n}","Options":[]},{"RuleId":{"RuleType":"CA","Id":1200},"Title":"Avoid using cref tags with a prefix","Category":"Documentation","Description":"The cref attribute in an XML documentation tag means \u0022code reference\u0022. It specifies that the inner text of the tag is a code element, such as a type, method, or property. Avoid using cref tags with prefixes, because it prevents the compiler from verifying references. It also prevents the Visual Studio integrated development environment (IDE) from finding and updating these symbol references during refactorings. It is recommended that you use the full syntax without prefixes to reference symbol names in cref tags.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1303},"Title":"Do not pass literals as localized parameters","Category":"Globalization","Description":"String literals that are embedded in source code are difficult to localize.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1304},"Title":"Specify CultureInfo","Category":"Globalization","Description":"When a System.Globalization.CultureInfo or System.IFormatProvider object is not supplied, the default value that is supplied by the overloaded member might not have the effect that you want in all locales. Also, .NET members choose default culture and formatting based on assumptions that might not be correct for your code. To ensure the code works as expected for your scenarios, you should supply culture-specific information according to the following guidelines:\r\nIf the value will be displayed to the user, use the current culture. See System.Globalization.CultureInfo.CurrentCulture.\r\n If the value will be stored and accessed by software, that is, persisted to a file or database, use the invariant culture. See System.Globalization.CultureInfo.InvariantCulture.\r\n If you do not know the destination of the value, have the data consumer or provider specify the culture.\r\nEven if the default behavior of the overloaded member is appropriate for your needs, it is better to explicitly call the culture-specific overload so that your code is self-documenting and more easily maintained.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nSystem.Globalization.CultureInfo.CurrentUICulture is used only to retrieve localized resources by using an instance of the System.Resources.ResourceManager class.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1305},"Title":"Specify IFormatProvider","Category":"Globalization","Description":"When a System.Globalization.CultureInfo or System.IFormatProvider object is not supplied, the default value that\u0027s supplied by the overloaded member might not have the effect that you want in all locales. Also, .NET members choose default culture and formatting based on assumptions that might not be correct for your code. To make sure that the code works as expected for your scenarios, you should supply culture-specific information according to the following guidelines:\r\nIf the value will be displayed to the user, use the current culture. See System.Globalization.CultureInfo.CurrentCulture.\r\n If the value will be stored and accessed by software (persisted to a file or database), use the invariant culture. See System.Globalization.CultureInfo.InvariantCulture.\r\n If you don\u0027t know the destination of the value, have the data consumer or provider specify the culture.\r\nEven if the default behavior of the overloaded member is appropriate for your needs, it\u0027s better to explicitly call the culture-specific overload so that your code is self-documenting and more easily maintained.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1307},"Title":"Specify StringComparison for clarity","Category":"Globalization","Description":"Many string compare operations provide an overload that accepts a System.StringComparison enumeration value as a parameter.\r\nWhenever an overload exists that takes a System.StringComparison parameter, it should be used instead of an overload that does not take this parameter. By explicitly setting this parameter, your code is often made clearer and easier to maintain. For more information, see Specifying string comparisons explicitly.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule does not consider the default System.StringComparison value used by the comparison method. Hence, it can be potentially noisy for methods that use the Ordinal string comparison by default and the user intended to use this default compare mode.\r\nIf you only want to see violations only for known string methods that use culture-specific string comparison by default, please use CA1310: Specify StringComparison for correctness instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1308},"Title":"Normalize strings to uppercase","Category":"Globalization","Description":"Strings should be normalized to uppercase. A small group of characters, when they are converted to lowercase, cannot make a round trip. To make a round trip means to convert the characters from one locale to another locale that represents character data differently, and then to accurately retrieve the original characters from the converted characters.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1309},"Title":"Use ordinal StringComparison","Category":"Globalization","Description":"Many string operations, most importantly the System.String.Compare and System.String.Equals methods, now provide an overload that accepts a System.StringComparison enumeration value as a parameter.\r\nWhen you specify either StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, the string comparison is non-linguistic. That is, the features that are specific to the natural language are ignored when comparison decisions are made. Ignoring natural language features means the decisions are based on simple byte comparisons and not on casing or equivalence tables that are parameterized by culture. As a result, by explicitly setting the parameter to either the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, your code often gains speed, increases correctness, and becomes more reliable.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1310},"Title":"Specify StringComparison for correctness","Category":"Globalization","Description":"A string comparison method that uses culture-specific string comparison by default can have potentially unintentional runtime behavior that does not match user intent. It is recommended that you use the overload with the System.StringComparison parameter for correctness and clarity of intent.\r\nThis rule flags string comparison methods that use the culture-specific System.StringComparison value by default. For more information, see String comparisons that use the current culture.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nIf you want to see violations for all string comparison methods, regardless of the default string comparison used by the method, please use CA1307: Specify StringComparison for clarity instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1311},"Title":"Specify a culture or use an invariant version","Category":"Globalization","Description":"Specify a culture or use an invariant culture to avoid implicit dependency on the current culture when calling ToUpper or ToLower. Using an invariant culture yields consistent results regardless of the culture of an application.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1401},"Title":"P/Invokes should not be visible","Category":"Interoperability","Description":"Methods that are marked with the System.Runtime.InteropServices.DllImportAttribute attribute (or methods that are defined by using the Declare keyword in Visual Basic) use Platform Invocation Services to access unmanaged code. Such methods should not be exposed. By keeping these methods private or internal, you make sure that your library cannot be used to breach security by allowing callers access to unmanaged APIs that they could not call otherwise.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1416},"Title":"Validate platform compatibility","Category":"Interoperability","Description":".NET 5 added new attributes, System.Runtime.Versioning.SupportedOSPlatformAttribute and System.Runtime.Versioning.UnsupportedOSPlatformAttribute, to annotate platform-specific APIs. Both attributes can be instantiated with or without version numbers as part of the platform name. They can also be applied multiple times with different platforms.\r\nAn unannotated API is considered to work on all operating system (OS) platforms.\r\n An API marked with [SupportedOSPlatform(\u0022platformName\u0022)] is considered to be portable to the specified OS platforms only. If the platform is a subset of another platform, the attribute implies that that platform is also supported.\r\n An API marked with [UnsupportedOSPlatform(\u0022platformName\u0022)] is considered to be unsupported on the specified OS platforms. If the platform is a subset of another platform, the attribute implies that that platform is also unsupported.\r\nYou can combine [SupportedOSPlatform] and [UnsupportedOSPlatform] attributes on a single API. In this case, the following rules apply:\r\nAllow list. If the lowest version for each OS platform is a [SupportedOSPlatform] attribute, the API is considered to only be supported by the listed platforms and unsupported by all other platforms. The list can have an [UnsupportedOSPlatform] attribute with the same platform, but only with a higher version, which denotes that the API is removed from that version.\r\n Deny list. If the lowest version for each OS platform is an [UnsupportedOSPlatform] attribute, then the API is considered to only be unsupported by the listed platforms and supported by all other platforms. The list can have a [SupportedOSPlatform] attribute with the same platform, but only with a higher version, which denotes that the API is supported since that version.\r\n Inconsistent list. If the lowest version for some platforms is [SupportedOSPlatform] but [UnsupportedOSPlatform] for other platforms, this combination is considered inconsistent. Some annotations on the API are ignored. In the future, we may introduce an analyzer that produces a warning in case of inconsistency.\r\nIf you access an API annotated with these attributes from the context of a different platform, you can see CA1416 violations.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1417},"Title":"Do not use OutAttribute on string parameters for P/Invokes","Category":"Interoperability","Description":"The .NET runtime automatically performs string interning. If an interned string marked with System.Runtime.InteropServices.OutAttribute is passed by value to a P/Invoke, the runtime can be destabilized.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1418},"Title":"Validate platform compatibility","Category":"Interoperability","Description":"The platform compatibility attributes derived from System.Runtime.Versioning.OSPlatformAttribute use string literals for operating system (OS) platform names with an optional version part. The string should consist of a known platform name and either no version part or a valid version part.\r\nThe known platform names list is populated from two places:\r\nThe PlatformName part of System.OperatingSystem guard methods named OperatingSystem.Is\u003CPlatformName\u003E[VersionAtLeast](). For example, guard method System.OperatingSystem.IsWindows adds Windows to the known platform names list.\r\n The project\u0027s MSBuild item group of SupportedPlatform items, including the default MSBuild SupportedPlatforms list. This is the project specific knowledge of known platforms. It allows class library authors to add more platforms into the known platforms list. For example:\r\n \u003CItemGroup\u003E\r\n \u003CSupportedPlatform Include=\u0022PlatformName\u0022 /\u003E\r\n \u003C/ItemGroup\u003E\r\nIf the platform string contains a version part, it should be a valid System.Version with the following format: major.minor[.build[.revision]].","Options":[]},{"RuleId":{"RuleType":"CA","Id":1419},"Title":"Provide a parameterless constructor that is as visible as the containing type for concrete types derived from \u0027System.Runtime.InteropServices.SafeHandle\u0027","Category":"Interoperability","Description":"Providing a public parameterless constructor for a type derived from System.Runtime.InteropServices.SafeHandle enables better performance and usage with source-generated interop solutions.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1420},"Title":"Property, type, or attribute requires runtime marshalling","Category":"Interoperability","Description":"Using features that require runtime marshalling when runtime marshalling is disabled will result in run-time exceptions.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1421},"Title":"Method uses runtime marshalling when DisableRuntimeMarshallingAttribute is applied","Category":"Interoperability","Description":"If a method uses runtime marshalling when runtime marshalling is disabled, it can cause unexpected behavior differences at run time due to different expectations of a type\u0027s native layout.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1422},"Title":"Validate platform compatibility - obsoleted APIs","Category":"Interoperability","Description":"Calling an API that\u0027s obsolete in a given OS (version) from a call site that\u0027s reachable from that OS (version) is not recommended. Consider calling a non-obsolete API instead, or guarding against calling the obsolete API on affected operating systems.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1501},"Title":"Avoid excessive inheritance","Category":"Maintainability","Description":"Deeply nested type hierarchies can be difficult to follow, understand, and maintain. This rule limits analysis to hierarchies in the same module.\r\nYou can configure this rule in the following ways:\r\nBy default, the rule excludes types from the System namespace. You can configure the rule to exclude other types or namespaces as well.\r\n You can configure the inheritance tree depth at which this rule fires.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1502},"Title":"Avoid excessive complexity","Category":"Maintainability","Description":"Cyclomatic complexity measures the number of linearly independent paths through the method, which is determined by the number and complexity of conditional branches. A low cyclomatic complexity generally indicates a method that is easy to understand, test, and maintain. The cyclomatic complexity is calculated from a control flow graph of the method and is given as follows:\r\ncyclomatic complexity = the number of edges - the number of nodes \u002B 1\r\nA node represents a logic branch point and an edge represents a line between nodes.\r\nThe rule reports a violation when the cyclomatic complexity of a method is more than 25. However, you can configure the threshold and also specify other kinds of symbols that the rule should analyze.\r\nYou can learn more about code metrics at Measure complexity of managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1505},"Title":"Avoid unmaintainable code","Category":"Maintainability","Description":"The rule reports a violation when the maintainability index of a type, method, field, property, or event is less than 10. However, you can configure the threshold.\r\nThe maintainability index is calculated by using the following metrics: lines of code, program volume, and cyclomatic complexity. (Program volume is a measure of the difficulty of understanding of a type or method that\u0027s based on the number of operators and operands in the code. Cyclomatic complexity is a measure of the structural complexity of the type or method. You can learn more about code metrics at Measure complexity and maintainability of managed code.\r\nA low maintainability index indicates that a type or method is probably difficult to maintain and would be a good candidate to redesign.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1506},"Title":"Avoid excessive class coupling","Category":"Maintainability","Description":"This rule measures class coupling by counting the number of unique type references that a type, method, field, property, or event contains. The default coupling threshold is 95 for types and 40 for other symbol kinds, and the thresholds are configurable.\r\nTypes, methods, and other symbols that have a high degree of class coupling can be difficult to maintain. It\u0027s a good practice to have types, methods, and other symbols that exhibit low coupling and high cohesion.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1507},"Title":"Use nameof in place of string","Category":"Maintainability","Description":"Rule CA1507 flags the use of a string literal as an argument to a method or constructor where a nameof (NameOf in Visual Basic) expression would add maintainability. The rule fires if all of the following conditions are met:\r\nThe argument is a string literal or constant.\r\n The argument corresponds to a string-typed parameter of the method or the constructor that\u0027s being invoked (that is, there is no conversion involved at the call site).\r\n Either:\r\n The declared name of the parameter is paramName and the constant value of the string literal matches the name of a parameter of the method, lambda, or local function within which the method or constructor is being invoked.\r\n The declared name of the parameter is propertyName and the constant value of the string literal matches the name of a property of the type within which the method or constructor is being invoked.\r\nRule CA1507 improves code maintainability in cases where the parameter may be renamed in the future, but the string literal is mistakenly not renamed. By using nameof, the symbol will be renamed when the parameter is renamed through a refactoring operation. In addition, any spelling mistakes in the name of the parameter are caught by the compiler.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1508},"Title":"Avoid dead conditional code","Category":"Maintainability","Description":"Methods can have conditional code, such as if statements, binary expressions (==, !=, \u003C, \u003E), null checks, etc. For example, consider the following code:\r\npublic void M(int i, int j)\r\n{\r\n if (i != 0)\r\n {\r\n return;\r\n }\r\n\r\n if (j != 0)\r\n {\r\n return;\r\n }\r\n\r\n // Below condition will always evaluate to \u0027false\u0027 as \u0027i\u0027 and \u0027j\u0027 are both \u00270\u0027 here.\r\n if (i != j)\r\n {\r\n // Code in this \u0027if\u0027 branch is dead code.\r\n // It can either be removed or refactored.\r\n ...\r\n }\r\n}\r\nC# and VB compilers perform analysis of conditional checks involving compile-time constant values that always evaluate to true or false. This analyzer performs data flow analysis of non-constant variables to determine redundant conditional checks involving non-constant values. In the preceding code, the analyzer determines that i and j are both 0 for all code paths that reach i != j check. Hence, this check will always evaluate to false at run time. The code inside the if statement is dead code and can be removed or refactored. Similarly, the analyzer tracks nullness of variables and reports redundant null checks.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis analyzer performs an expensive dataflow analysis of non-constant values. This can increase the overall compile time on certain code bases.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1509},"Title":"Invalid entry in code metrics configuration file","Category":"Maintainability","Description":"The analysis rules for code metrics allow you to supply an additional file in your project named CodeMetricsConfig.txt. This file contains entries to configure code-metric thresholds for analysis. The following rules are configurable in this file:\r\nCA1501: Avoid excessive inheritance\r\n CA1502: Avoid excessive complexity\r\n CA1505: Avoid unmaintainable code\r\n CA1506: Avoid excessive class coupling\r\nThis configuration file expects each entry to be in following format:\r\n\u0027RuleId\u0027(Optional \u0027SymbolKind\u0027): \u0027Threshold\u0027\r\nValid values for RuleId are CA1501, CA1502, CA1505, and CA1506.\r\n Valid values for the optional SymbolKind are Assembly, Namespace, Type, Method, Field, Event, and Property.\r\n Valid values for Threshold are non-negative integers.\r\n Lines starting with \u0027#\u0027 are treated as comment lines.\r\nFor example, the following is a valid configuration file:\r\n# Comment text\r\n\r\nCA1501: 1\r\n\r\nCA1502(Type): 4\r\nCA1502(Method): 2\r\nAn invalid entry in this configuration file is flagged with the CA1509 diagnostic.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1510},"Title":"Use ArgumentNullException throw helper","Category":"Maintainability","Description":"Argument checks have a substantial impact on code size and often dominate the code for small functions and property setters. These checks prevent inlining and cause substantial instruction-cache pollution. Throw-helper methods such as System.ArgumentNullException.ThrowIfNull are simpler and more efficient than if blocks that construct a new exception instance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1511},"Title":"Use ArgumentException throw helper","Category":"Maintainability","Description":"Argument checks have a substantial impact on code size and often dominate the code for small functions and property setters. These checks prevent inlining and cause substantial instruction-cache pollution. Throw-helper methods such as System.ArgumentException.ThrowIfNullOrEmpty(System.String,System.String) are simpler and more efficient than if blocks that construct a new exception instance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1512},"Title":"Use ArgumentOutOfRangeException throw helper","Category":"Maintainability","Description":"Argument checks have a substantial impact on code size and often dominate the code for small functions and property setters. These checks prevent inlining and cause substantial instruction-cache pollution. Throw-helper methods such as System.ArgumentOutOfRangeException.ThrowIfGreaterThan are simpler and more efficient than if blocks that construct a new exception instance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1513},"Title":"Use ObjectDisposedException throw helper","Category":"Maintainability","Description":"Object checks have a substantial impact on code size and often dominate the code for small functions and property setters. These checks prevent inlining and cause substantial instruction-cache pollution. Throw-helper methods such as System.ObjectDisposedException.ThrowIf%2A are simpler and more efficient than if blocks that construct a new exception instance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1514},"Title":"Avoid redundant length argument","Category":"Maintainability","Description":"An explicitly calculated length argument can be error-prone and is unnecessary when you\u0027re slicing to the end of a string or buffer.\r\nCode that omits the length argument is more readable and maintainable.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1515},"Title":"Consider making public types internal","Category":"Maintainability","Description":"Unlike a class library, an application\u0027s API isn\u0027t typically referenced publicly, so types can be marked internal.\r\nInternal types, in turn, can benefit from various code analyzers that target non-public APIs.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1700},"Title":"Do not name enum values \u0027Reserved\u0027","Category":"Naming","Description":"This rule assumes that an enumeration member that has a name that contains \u0022reserved\u0022 is not currently used but is a placeholder to be renamed or removed in a future version. Renaming or removing a member is a breaking change. You should not expect users to ignore a member just because its name contains \u0022reserved\u0022, nor can you rely on users to read or abide by documentation. Furthermore, because reserved members appear in object browsers and smart integrated development environments, they can cause confusion about which members are actually being used.\r\nInstead of using a reserved member, add a new member to the enumeration in the future version. In most cases the addition of the new member is not a breaking change, as long as the addition does not cause the values of the original members to change.\r\nIn a limited number of cases the addition of a member is a breaking change even when the original members retain their original values. Primarily, the new member cannot be returned from existing code paths without breaking callers that use a switch (Select in Visual Basic) statement on the return value that encompasses the whole member list and that throw an exception in the default case. A secondary concern is that client code might not handle the change in behavior from reflection methods such as System.Enum.IsDefined. Accordingly, if the new member has to be returned from existing methods or a known application incompatibility occurs because of poor reflection usage, the only nonbreaking solution is to:\r\nAdd a new enumeration that contains the original and new members.\r\n Mark the original enumeration with the System.ObsoleteAttribute attribute. Follow the same procedure for any externally visible types or members that expose the original enumeration.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1707},"Title":"Identifiers should not contain underscores","Category":"Naming","Description":"By convention, identifier names do not contain the underscore (_) character. The rule checks namespaces, types, members, and parameters.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1708},"Title":"Identifiers should differ by more than case","Category":"Naming","Description":"Identifiers for namespaces, types, members, and parameters cannot differ only by case because languages that target the common language runtime are not required to be case-sensitive. For example, Visual Basic is a widely used case-insensitive language.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1710},"Title":"Identifiers should have correct suffix","Category":"Naming","Description":"By convention, the names of types that extend certain base types or that implement certain interfaces, or types derived from these types, have a suffix that is associated with the base type or interface.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.\r\nThe following table lists the base types and interfaces that have associated suffixes.\r\nBase type/Interface Suffix System.Attribute Attribute System.EventArgs EventArgs System.Exception Exception System.Collections.ICollection Collection System.Collections.IDictionary Dictionary System.Collections.IEnumerable Collection System.Collections.Generic.IReadOnlyDictionary%602 Dictionary System.Collections.Queue Collection or Queue System.Collections.Stack Collection or Stack System.Collections.Generic.ICollection%601 Collection System.Collections.Generic.IDictionary%602 Dictionary System.Data.DataSet DataSet System.Data.DataTable Collection or DataTable System.IO.Stream Stream System.Security.IPermission Permission System.Security.Policy.IMembershipCondition Condition An event-handler delegate. EventHandler\r\nTypes that implement System.Collections.ICollection and are a generalized type of data structure, such as a dictionary, stack, or queue, are allowed names that provide meaningful information about the intended usage of the type.\r\nTypes that implement System.Collections.ICollection and are a collection of specific items have names that end with the word \u0027Collection\u0027. For example, a collection of System.Collections.Queue objects would have the name \u0027QueueCollection\u0027. The \u0027Collection\u0027 suffix signifies that the members of the collection can be enumerated by using the foreach (For Each in Visual Basic) statement.\r\nTypes that implement System.Collections.IDictionary or System.Collections.Generic.IReadOnlyDictionary%602 have names that end with the word \u0027Dictionary\u0027 even if the type also implements System.Collections.IEnumerable or System.Collections.ICollection. The \u0027Collection\u0027 and \u0027Dictionary\u0027 suffix naming conventions enable users to distinguish between the following two enumeration patterns.\r\nTypes with the \u0027Collection\u0027 suffix follow this enumeration pattern.\r\nforeach(SomeType x in SomeCollection) { }\r\nTypes with the \u0027Dictionary\u0027 suffix follow this enumeration pattern.\r\nforeach(SomeType x in SomeDictionary.Values) { }\r\nA System.Data.DataSet object consists of a collection of System.Data.DataTable objects, which consist of collections of System.Data.DataColumn and System.Data.DataRow objects, among others. These collections implement System.Collections.ICollection through the base System.Data.InternalDataCollectionBase class.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1711},"Title":"Identifiers should not have incorrect suffix","Category":"Naming","Description":"By convention, only the names of types that extend certain base types or that implement certain interfaces, or types derived from these types, should end with specific reserved suffixes. Other type names should not use these reserved suffixes.\r\nThe following table lists the reserved suffixes and the base types and interfaces with which they are associated.\r\nSuffix Base type/Interface Attribute System.Attribute Collection System.Collections.ICollectionSystem.Collections.IEnumerableSystem.Collections.QueueSystem.Collections.StackSystem.Collections.Generic.ICollection%601System.Data.DataSetSystem.Data.DataTable Dictionary System.Collections.IDictionarySystem.Collections.Generic.IDictionary%602 EventArgs System.EventArgs EventHandler An event-handler delegate Exception System.Exception Permission System.Security.IPermission Queue System.Collections.Queue Stack System.Collections.Stack Stream System.IO.Stream\r\nIn addition, the following suffixes should not be used:\r\nDelegate\r\n Enum\r\n Impl (use Core instead)\r\n Ex or similar suffix to distinguish it from an earlier version of the same type\r\n Flag or Flags for enum types\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code. For more information, see Naming guidelines: Classes, Structs, and Interfaces.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1712},"Title":"Do not prefix enum values with type name","Category":"Naming","Description":"Names of enumeration members are not prefixed with the type name because type information is expected to be provided by development tools.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the time that is required for to learn a new software library, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1713},"Title":"Events should not have before or after prefix","Category":"Naming","Description":"Event names should describe the action that raises the event. To name related events that are raised in a specific sequence, use the present or past tense to indicate the relative position in the sequence of actions. For example, when naming a pair of events that is raised when closing a resource, you might name it \u0027Closing\u0027 and \u0027Closed\u0027, instead of \u0027BeforeClose\u0027 and \u0027AfterClose\u0027.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1714},"Title":"Flags enums should have plural names","Category":"Naming","Description":"Types that are marked with System.FlagsAttribute have names that are plural because the attribute indicates that more than one value can be specified. For example, an enumeration that defines the days of the week might be intended for use in an application where you can specify multiple days. This enumeration should have the System.FlagsAttribute and could be called \u0027Days\u0027. A similar enumeration that allows only a single day to be specified would not have the attribute, and could be called \u0027Day\u0027.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1715},"Title":"Identifiers should have correct prefix","Category":"Naming","Description":"By convention, the names of certain programming elements start with a specific prefix.\r\nInterface names should start with an uppercase \u0027I\u0027 followed by another uppercase letter. This rule reports violations for interface names such as \u0027MyInterface\u0027 and \u0027IsolatedInterface\u0027.\r\nGeneric type parameter names should start with an uppercase \u0027T\u0027 and optionally may be followed by another uppercase letter. This rule reports violations for generic type parameter names such as \u0027V\u0027 and \u0027Type\u0027.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the learning curve that is required for new software libraries, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":["exclude_single_letter_type_parameters"]},{"RuleId":{"RuleType":"CA","Id":1716},"Title":"Identifiers should not match keywords","Category":"Naming","Description":"Identifiers for namespaces, types, and virtual and interface members should not match keywords that are defined by languages that target the common language runtime. Depending on the language that is used and the keyword, compiler errors and ambiguities can make the library difficult to use.\r\nThis rule checks against keywords in the following languages:\r\nVisual Basic\r\n C#\r\n C\u002B\u002B/CLI\r\nCase-insensitive comparison is used for Visual Basic keywords, and case-sensitive comparison is used for the other languages.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1717},"Title":"Only FlagsAttribute enums should have plural names","Category":"Naming","Description":"Naming conventions dictate that a plural name for an enumeration indicates that more than one value of the enumeration can be specified simultaneously. The System.FlagsAttribute tells compilers that the enumeration should be treated as a bit field that enables bitwise operations on the enumeration.\r\nIf only one value of an enumeration can be specified at a time, the name of the enumeration should be a singular word. For example, an enumeration that defines the days of the week might be intended for use in an application where you can specify multiple days. This enumeration should have the System.FlagsAttribute and could be called \u0027Days\u0027. A similar enumeration that allows only a single day to be specified would not have the attribute, and could be called \u0027Day\u0027.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This reduces the time that is required to learn a new software library, and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1720},"Title":"Identifiers should not contain type names","Category":"Naming","Description":"Names of parameters and members are better used to communicate their meaning than to describe their type, which is expected to be provided by development tools. For names of members, if a data type name must be used, use a language-independent name instead of a language-specific one. For example, instead of the C# type name int, use the language-independent data type name, Int32.\r\nEach discrete token in the name of the parameter or member is checked against the following language-specific data type names in a case-insensitive manner:\r\nBool\r\n WChar\r\n Int8\r\n UInt8\r\n Short\r\n UShort\r\n Int\r\n UInt\r\n Integer\r\n UInteger\r\n Long\r\n ULong\r\n Unsigned\r\n Signed\r\n Float\r\n Float32\r\n Float64\r\nIn addition, the names of a parameter are also checked against the following language-independent data type names in a case-insensitive manner:\r\nObject\r\n Boolean\r\n Char\r\n String\r\n SByte\r\n Byte\r\n UByte\r\n Int16\r\n UInt16\r\n Int32\r\n UInt32\r\n Int64\r\n UInt64\r\n IntPtr\r\n Ptr\r\n Pointer\r\n UInptr\r\n UPtr\r\n UPointer\r\n Single\r\n Double\r\n Decimal\r\n Guid","Options":[]},{"RuleId":{"RuleType":"CA","Id":1721},"Title":"Property names should not match get methods","Category":"Naming","Description":"\u0022Get\u0022 methods and properties should have names that clearly distinguish their function.\r\nNaming conventions provide a common look for libraries that target the common language runtime. This consistency reduces the time that\u0027s required to learn a new software library and increases customer confidence that the library was developed by someone who has expertise in developing managed code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1724},"Title":"Type names should not match namespaces","Category":"Naming","Description":"User-created type names should not match the names of referenced namespaces that have externally visible types. Violating this rule can reduce the usability of your library.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1725},"Title":"Parameter names should match base declaration","Category":"Naming","Description":"Consistent naming of parameters in an override hierarchy increases the usability of the method overrides. A parameter name in a derived method that differs from the name in the base declaration can cause confusion about whether the method is an override of the base method or a new overload of the method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1727},"Title":"Use PascalCase for named placeholders","Category":"Naming","Description":"A named placeholder used with Microsoft.Extensions.Logging.ILogger should be PascalCase, a naming convention where the first letter of each compound word in a name is capitalized. This naming convention is recommended for structured logging, where each named placeholder is used as a property name in the structured data.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1801},"Title":"Review unused parameters","Category":"Usage","Description":"Review parameters in non-virtual methods that are not used in the method body to make sure no incorrectness exists around failure to access them. Unused parameters incur maintenance and performance costs.\r\nSometimes, a violation of this rule can point to an implementation bug in the method. For example, the parameter should have been used in the method body. Suppress warnings of this rule if the parameter must exist because of backward compatibility.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1802},"Title":"Use Literals Where Appropriate","Category":"Performance","Description":"The value of a static readonly field is computed at run time when the static constructor for the declaring type is called. If the static readonly field is initialized when it is declared and a static constructor is not declared explicitly, the compiler emits a static constructor to initialize the field.\r\nThe value of a const field is computed at compile time and stored in the metadata, which improves run-time performance when it is compared to a static readonly field.\r\nBecause the value assigned to the targeted field is computable at compile time, change the declaration to a const field so that the value is computed at compile time instead of at run time.","Options":["required_modifiers"]},{"RuleId":{"RuleType":"CA","Id":1805},"Title":"Do not initialize unnecessarily","Category":"Performance","Description":"The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1806},"Title":"Do not ignore method results","Category":"Performance","Description":"Unnecessary object creation and the associated garbage collection of the unused object degrade performance.\r\nStrings are immutable and methods such as System.String.ToUpper return a new instance of a string instead of modifying the instance of the string in the calling method.\r\nIgnoring HRESULT or an error code can lead to low-resource conditions or unexpected behavior in error conditions.\r\nLINQ methods are known to not have side effects, and the result should not be ignored.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1810},"Title":"Initialize reference type static fields inline","Category":"Performance","Description":"When a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance constructor of the type to make sure that the static constructor was previously called. Static initialization is triggered when any static member is accessed or when an instance of the type is created. However, static initialization is not triggered if you declare a variable of the type but do not use it, which can be important if the initialization changes global state.\r\nWhen all static data is initialized inline and an explicit static constructor is not declared, common intermediate language (CIL) compilers add the beforefieldinit flag and an implicit static constructor, which initializes the static data, to the CIL type definition. When the JIT compiler encounters the beforefieldinit flag, most of the time the static constructor checks are not added. Static initialization is guaranteed to occur at some time before any static fields are accessed but not before a static method or instance constructor is invoked. Note that static initialization can occur at any time after a variable of the type is declared.\r\nStatic constructor checks can decrease performance. Often a static constructor is used only to initialize static fields, in which case you must only make sure that static initialization occurs before the first access of a static field. The beforefieldinit behavior is appropriate for these and most other types. It is only inappropriate when static initialization affects global state and one of the following is true:\r\nThe effect on global state is expensive and is not required if the type is not used.\r\n The global state effects can be accessed without accessing any static fields of the type.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1812},"Title":"Avoid uninstantiated internal classes","Category":"Performance","Description":"This rule tries to locate a call to one of the constructors of the type and reports a violation if no call is found.\r\nThe following types are not examined by this rule:\r\nValue types\r\n Abstract types\r\n Enumerations\r\n Delegates\r\n Compiler-emitted array types\r\n Types that can\u0027t be instantiated and that only define static methods.\r\nIf you apply System.Runtime.CompilerServices.InternalsVisibleToAttribute to the assembly that\u0027s being analyzed, this rule doesn\u0027t flag types that are marked as internal (Friend in Visual Basic) by default, because a field may be used by a friend assembly. To analyze the assembly anyway, see Configure code to analyze.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1813},"Title":"Avoid unsealed attributes","Category":"Performance","Description":".NET provides methods for retrieving custom attributes. By default, these methods search the attribute inheritance hierarchy. For example, System.Attribute.GetCustomAttribute searches for the specified attribute type or any attribute type that extends the specified attribute type. Sealing the attribute eliminates the search through the inheritance hierarchy, and can improve performance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1814},"Title":"Prefer jagged arrays over multidimensional","Category":"Performance","Description":"In a multidimensional array, each element in each dimension has the same, fixed size as the other elements in that dimension. In a jagged array, which is an array of arrays, each inner array can be of a different size. By only using the space that\u0027s needed for a given array, no space is wasted. This rule, CA1814, recommends switching to a jagged array to conserve memory.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1815},"Title":"Override equals and operator equals on value types","Category":"Performance","Description":"For non-blittable value types, the inherited implementation of System.Object.Equals%2A uses the System.Reflection library to compare the contents of all fields. Reflection is computationally expensive, and comparing every field for equality might be unnecessary. If you expect users to compare or sort instances, or use them as hash table keys, your value type should implement System.Object.Equals%2A. If your programming language supports operator overloading, you should also provide an implementation of the equality and inequality operators.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1816},"Title":"Call GC.SuppressFinalize correctly","Category":"Usage","Description":"The System.IDisposable.Dispose method lets users release resources at any time before the object becoming available for garbage collection. If the System.IDisposable.Dispose method is called, it frees resources of the object. This makes finalization unnecessary. System.IDisposable.Dispose should call System.GC.SuppressFinalize so the garbage collector doesn\u0027t call the finalizer of the object.\r\nTo prevent derived types with finalizers from having to reimplement System.IDisposable and to call it, unsealed types without finalizers should still call System.GC.SuppressFinalize.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1819},"Title":"Properties should not return arrays","Category":"Performance","Description":"Arrays returned by properties are not write-protected, even if the property is read-only. To keep the array tamper-proof, the property must return a copy of the array. Typically, users won\u0027t understand the adverse performance implications of calling such a property. Specifically, they might use the property as an indexed property.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1820},"Title":"Test for empty strings using string length","Category":"Performance","Description":"Comparing strings using the System.String.Length property or the System.String.IsNullOrEmpty method is faster than using System.Object.Equals%2A. This is because System.Object.Equals%2A executes significantly more CIL instructions than either System.String.IsNullOrEmpty%2A or the number of instructions executed to retrieve the System.String.Length%2A property value and compare it to zero.\r\nFor null strings, System.Object.Equals%2A and \u003Cstring\u003E.Length == 0 behave differently. If you try to get the value of the System.String.Length%2A property on a null string, the common language runtime throws a System.NullReferenceException. If you perform a comparison between a null string and the empty string, the common language runtime does not throw an exception and returns false. Testing for null does not significantly affect the relative performance of these two approaches. When targeting .NET Framework 2.0 or later, use the System.String.IsNullOrEmpty%2A method. Otherwise, use the System.String.Length%2A == 0 comparison whenever possible.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1821},"Title":"Remove empty finalizers","Category":"Performance","Description":"Whenever you can, avoid finalizers because of the additional performance overhead that\u0027s involved in tracking object lifetime. The garbage collector runs the finalizer before it collects the object. This means that at least two collections are required to collect the object. An empty finalizer incurs this added overhead without any benefit.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1822},"Title":"Mark members as static","Category":"Performance","Description":"Members that do not access instance data or call instance methods can be marked as static (Shared in Visual Basic). After you mark the methods as static, the compiler will emit nonvirtual call sites to these members. Emitting nonvirtual call sites will prevent a check at run time for each call that makes sure that the current object pointer is non-null. This can achieve a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1823},"Title":"Avoid unused private fields","Category":"Performance","Description":"Private fields were detected that do not appear to be accessed in the assembly.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1824},"Title":"Mark assemblies with NeutralResourcesLanguageAttribute","Category":"Performance","Description":"The System.Resources.NeutralResourcesLanguageAttribute attribute informs the resource manager of an app\u0027s default culture. If the default culture\u0027s resources are embedded in the app\u0027s main assembly, and System.Resources.ResourceManager has to retrieve resources that belong to the same culture as the default culture, the System.Resources.ResourceManager automatically uses the resources located in the main assembly instead of searching for a satellite assembly. This bypasses the usual assembly probe, improves lookup performance for the first resource you load, and can reduce your working set.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ETip\u003C/p\u003E\r\nSee Package and deploy resources for the process that System.Resources.ResourceManager uses to probe for resource files.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1825},"Title":"Avoid zero-length array allocations","Category":"Performance","Description":"Initializing a zero-length array leads to an unnecessary memory allocation. Instead, use the statically allocated empty array instance by calling the System.Array.Empty method. The memory allocation is shared across all invocations of this method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1826},"Title":"Use property instead of Linq Enumerable method","Category":"Performance","Description":"This rule flags the System.Linq.Enumerable LINQ method calls on collections of types that have equivalent but more efficient properties to fetch the same data.\r\nThis rule analyzes collection types that implement System.Collections.Generic.IReadOnlyList%601 but not System.Collections.Generic.IList%601.\r\nThis rule flags calls to the following methods on these collection types:\r\nSystem.Linq.Enumerable.Count\r\n System.Linq.Enumerable.First\r\n System.Linq.Enumerable.FirstOrDefault\r\n System.Linq.Enumerable.Last\r\n System.Linq.Enumerable.LastOrDefault\r\nThe analyzed collection types and methods may be extended in the future to cover more cases.","Options":["exclude_ordefault_methods"]},{"RuleId":{"RuleType":"CA","Id":1827},"Title":"Do not use Count()/LongCount() when Any() can be used","Category":"Performance","Description":"This rule flags Count() and LongCount() LINQ method calls that are used to check if the collection has at least one element. These methods enumerate the entire collection to compute the count. The same check is faster with the Any() method as it avoids enumerating the collection.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule is similar to CA1860: Avoid using \u0027Enumerable.Any()\u0027 extension method. However that rule suggests using the Count property, while this rule applies to the Linq Count() extension method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1828},"Title":"Do not use CountAsync/LongCountAsync when AnyAsync can be used","Category":"Performance","Description":"This rule flags the Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync%2A and Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.LongCountAsync%2A LINQ method calls used to check if the collection has at least one element. These method calls require enumerating the entire collection to compute the count. The same check is faster with the Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AnyAsync%2A method as it avoids enumerating the collection.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1829},"Title":"Use Length/Count property instead of Enumerable.Count method","Category":"Performance","Description":"This rule flags the System.Linq.Enumerable.Count%2A LINQ method calls on collections of types that have equivalent, but more efficient Length or Count property to fetch the same data. Length or Count property does not enumerate the collection, hence is more efficient.\r\nThis rule flags System.Linq.Enumerable.Count%2A calls on the following collection types with Length property:\r\nSystem.Array\r\n System.Collections.Immutable.ImmutableArray%601\r\nThis rule flags System.Linq.Enumerable.Count%2A calls on the following collection types with the Count property:\r\nSystem.Collections.ICollection\r\n System.Collections.Generic.ICollection%601\r\n System.Collections.Generic.IReadOnlyCollection%601\r\nThe analyzed collection types may be extended in the future to cover more cases.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1830},"Title":"Prefer strongly-typed Append and Insert method overloads on StringBuilder","Category":"Performance","Description":"System.Text.StringBuilder.Append%2A and System.Text.StringBuilder.Insert%2A provide overloads for multiple types beyond System.String. When possible, prefer the strongly-typed overloads over using ToString() and the string-based overload.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1831},"Title":"Use AsSpan instead of Range-based indexers for string when appropriate","Category":"Performance","Description":"This rule fires when you use a range-indexer on a string and assign it to a span type. The range indexer on a System.Span%601 is a non-copying System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_ operation, but for the range indexer on a string, the method System.String.Substring%2A?#System_String_Substring_System_Int32_System_Int32_ will be used instead of System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_. This produces a copy of the requested portion of the string. This copy is usually unnecessary when it\u0027s implicitly used as a System.ReadOnlySpan%601 or System.ReadOnlyMemory%601 value. If a copy isn\u0027t intended, use the System.MemoryExtensions.AsSpan%2A?#System_MemoryExtensions_AsSpan_System_String_AsSpan method to avoid the unnecessary copy. If the copy is intended, either assign it to a local variable first or add an explicit cast. The analyzer only reports when an implicit cast is used on the result of the range indexer operation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1832},"Title":"Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array","Category":"Performance","Description":"The range indexer on a System.Span%601 is a non-copying System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_ operation. But for the range indexer on an array, the method System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A will be used instead of System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_, which produces a copy of the requested portion of the array. This copy is usually unnecessary when it\u0027s implicitly used as a System.ReadOnlySpan%601 or System.ReadOnlyMemory%601 value. If a copy isn\u0027t intended, use the System.MemoryExtensions.AsSpan%2A?#System_MemoryExtensions_AsSpan__1___0___ or System.MemoryExtensions.AsMemory%2A?#System_MemoryExtensions_AsMemory__1___0___ method to avoid the unnecessary copy. If the copy is intended, either assign it to a local variable first or add an explicit cast.\r\nThe analyzer only reports when an implicit cast is used on the result of the range indexer operation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1833},"Title":"Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array","Category":"Performance","Description":"The range indexer on a System.Span%601 is a non-copying System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_ operation. But for the range indexer on an array, the method System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A will be used instead of System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_, which produces a copy of the requested portion of the array. This copy is usually unnecessary when it\u0027s implicitly used as a System.Span%601 or System.Memory%601 value. If a copy isn\u0027t intended, use the System.MemoryExtensions.AsSpan%2A?#System_MemoryExtensions_AsSpan__1___0___ or System.MemoryExtensions.AsMemory%2A?#System_MemoryExtensions_AsMemory__1___0___ method to avoid the unnecessary copy. If the copy is intended, either assign it to a local variable first or add an explicit cast. The analyzer only reports when an implicit cast is used on the result of the range indexer operation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1834},"Title":"Use StringBuilder.Append(char) for single character strings","Category":"Performance","Description":"When calling StringBuilder.Append with a unit length string, consider using a const char rather than a unit length const string to improve performance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1835},"Title":"Prefer the memory-based overloads of ReadAsync/WriteAsync methods in stream-based classes","Category":"Performance","Description":"The memory-based method overloads have a more efficient memory usage than the byte array-based ones.\r\nThe rule works on ReadAsync and WriteAsync invocations of any class that inherits from System.IO.Stream.\r\nThe rule only works when the method is preceded by the await keyword.\r\nDetected method Suggested method System.IO.Stream.ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken) System.IO.Stream.ReadAsync(System.Memory{System.Byte},System.Threading.CancellationToken) System.IO.Stream.ReadAsync(System.Byte[],System.Int32,System.Int32) System.IO.Stream.ReadAsync(System.Memory{System.Byte},System.Threading.CancellationToken) with CancellationToken set to default in C#, or Nothing in Visual Basic. System.IO.Stream.WriteAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken) System.IO.Stream.WriteAsync(System.ReadOnlyMemory{System.Byte},System.Threading.CancellationToken) System.IO.Stream.WriteAsync(System.Byte[],System.Int32,System.Int32) System.IO.Stream.WriteAsync(System.ReadOnlyMemory{System.Byte},System.Threading.CancellationToken) with CancellationToken set to default in C#, or Nothing in Visual Basic.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003EImportant\u003C/p\u003E\r\nMake sure to pass the offset and count integer arguments to the created Memory or ReadOnlyMemory instances.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nRule CA1835 is available in all .NET versions where the memory-based overloads are available:\r\n .NET Standard 2.1 and above.\r\n .NET Core 2.1 and above.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1836},"Title":"Prefer IsEmpty over Count when available","Category":"Performance","Description":"This rule flags the calls to the Count and Length properties or System.Linq.Enumerable.Count%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29 and System.Linq.Enumerable.LongCount%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29 LINQ methods when they are used to determine if the object contains any items and the object has a more efficient IsEmpty property.\r\nThe analysis of this rule originally overlapped with similar rules CA1827, CA1828, and CA1829; the analyzers of such rules were merged along with the one for CA1836 to report the best diagnosis in case of overlap.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1837},"Title":"Use Environment.ProcessId instead of Process.GetCurrentProcess().Id","Category":"Performance","Description":"System.Diagnostics.Process.GetCurrentProcess().Id is expensive:\r\nIt allocates a System.Diagnostics.Process instance, usually just to get the Id.\r\n The System.Diagnostics.Process instance needs to be disposed, which has a performance impact.\r\n It\u0027s easy to forget to call System.Diagnostics.Process.Dispose on the System.Diagnostics.Process instance.\r\n If nothing else besides Id uses the Process instance, then the linked size grows unnecessarily by increasing the graph of types referenced.\r\n It is somewhat difficult to discover or find this API.\r\nSystem.Environment.ProcessId avoids all the above.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nRule CA1837 is available starting on .NET 5.0.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1838},"Title":"Avoid StringBuilder parameters for P/Invokes","Category":"Performance","Description":"Marshalling of StringBuilder always creates a native buffer copy, resulting in multiple allocations for one P/Invoke call. To marshal a StringBuilder as a P/Invoke parameter, the runtime will:\r\nAllocate a native buffer.\r\n If it is an In parameter, copy the contents of the StringBuilder to the native buffer.\r\n If it is an Out parameter, copy the native buffer into a newly allocated managed array.\r\nBy default, StringBuilder is In and Out.\r\nFor more information about marshalling strings, see Default marshalling for strings.\r\nThis rule is disabled by default, because it can require case-by-case analysis of whether the violation is of interest and potentially non-trivial refactoring to address the violation. Users can explicitly enable this rule by configuring its severity.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1839},"Title":"Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName","Category":"Performance","Description":"System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName is expensive:\r\nIt allocates a System.Diagnostics.Process and System.Diagnostics.ProcessModule instance, usually just to get the FileName.\r\n The System.Diagnostics.Process instance needs to be disposed, which has a performance impact.\r\n It\u0027s easy to forget to call System.Diagnostics.Process.Dispose on the System.Diagnostics.Process instance.\r\n If nothing else besides FileName uses the Process instance, then the linked size grows unnecessarily by increasing the graph of types referenced.\r\n It is somewhat difficult to discover or find this API.\r\nSystem.Environment.ProcessPath avoids all of these downsides and produces the same information.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nSystem.Environment.ProcessPath is available starting in .NET 6.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1840},"Title":"Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId","Category":"Performance","Description":"System.Environment.CurrentManagedThreadId is a compact and efficient replacement of the Thread.CurrentThread.ManagedThreadId pattern.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1841},"Title":"Prefer Dictionary Contains methods","Category":"Performance","Description":"Calling Contains on the Keys or Values collection can often be more expensive than calling ContainsKey or ContainsValue on the dictionary itself:\r\nMany dictionary implementations lazily instantiate the key and value collections, which means that accessing the Keys or Values collection may result in extra allocations.\r\n You may end up calling an extension method on System.Collections.Generic.IEnumerable%601 if the keys or values collection uses explicit interface implementation to hide methods on System.Collections.Generic.ICollection%601. This can lead to reduced performance, especially when accessing the key collection. Most dictionary implementations are able to provide a fast O(1) containment check for keys, while the Contains extension method on System.Collections.Generic.IEnumerable%601 usually does a slow O(n) containment check.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1842},"Title":"Do not use \u0027WhenAll\u0027 with a single task","Category":"Performance","Description":"Using WhenAll with a single task may result in performance loss.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1843},"Title":"Do not use \u0027WaitAll\u0027 with a single task","Category":"Performance","Description":"Using WaitAll with a single task may result in performance loss.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1844},"Title":"Provide memory-based overrides of async methods when subclassing \u0027Stream\u0027","Category":"Performance","Description":"The memory-based ReadAsync and WriteAsync methods were added to improve performance, which they accomplish in multiple ways:\r\nThey return ValueTask and ValueTask\u003Cint\u003E instead of Task and Task\u003Cint\u003E, respectively.\r\n They allow any type of buffer to be passed in without having to perform an extra copy to an array.\r\nIn order to realize these performance benefits, types that derive from System.IO.Stream must provide their own memory-based implementation. Otherwise, the default implementation will be forced to copy the memory into an array in order to call the array-based implementation, resulting in reduced performance. When the caller passes in a System.Memory%601 or System.ReadOnlyMemory%601 instance that\u0027s not backed by an array, performance is affected more.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1845},"Title":"Use span-based \u0027string.Concat\u0027","Category":"Performance","Description":"Calling Substring produces a copy of the extracted substring. By using AsSpan instead of Substring and calling the overload of string.Concat that accepts spans, you can eliminate the unnecessary string allocation.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1846},"Title":"Prefer AsSpan over Substring","Category":"Performance","Description":"Substring allocates a new string object on the heap and performs a full copy of the extracted text. String manipulation is a performance bottleneck for many programs. Allocating many small, short-lived strings on a hot path can create enough collection pressure to impact performance. The O(n) copies created by Substring become relevant when the substrings get large. The System.Span%601 and System.ReadOnlySpan%601 types were created to solve these performance problems.\r\nMany APIs that accept strings also have overloads that accept a ReadOnlySpan\u003CSystem.Char\u003E argument. When such overloads are available, you can improve performance by calling AsSpan instead of Substring.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1847},"Title":"Use string.Contains(char) instead of string.Contains(string) with single characters","Category":"Performance","Description":"When searching for a single character, using string.Contains(char) offers better performance than string.Contains(string).","Options":[]},{"RuleId":{"RuleType":"CA","Id":1848},"Title":"Use the LoggerMessage delegates","Category":"Performance","Description":"For high-performance logging scenarios, use the Microsoft.Extensions.Logging.LoggerMessage pattern.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1849},"Title":"Call async methods when in an async method","Category":"Performance","Description":"In a method which is already asynchronous, calls to other methods should be to their async versions, where they exist.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1850},"Title":"Prefer static HashData method over ComputeHash","Category":"Performance","Description":"Static HashData methods were introduced in .NET 5 on the following types:\r\nSystem.Security.Cryptography.MD5\r\n System.Security.Cryptography.SHA1\r\n System.Security.Cryptography.SHA256\r\n System.Security.Cryptography.SHA384\r\n System.Security.Cryptography.SHA512\r\nThese methods help simplify code in cases where you just want to hash some data.\r\nIt\u0027s more efficient to use theses static HashData methods than to create and manage a HashAlgorithm instance to call ComputeHash.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1851},"Title":"Possible multiple enumerations of IEnumerable collection","Category":"Performance","Description":"A collection of type IEnumerable or IEnumerable\u003CT\u003E has the ability to defer enumeration when it\u0027s generated. Many LINQ methods, such as Select, use deferred execution. Enumeration starts when the collection is passed into a LINQ enumeration method, like ElementAt, or used in a for each statement. The enumeration result is not calculated once and cached, like Lazy.\r\nIf the enumeration operation itself is expensive, for example, a query into a database, multiple enumerations would hurt the performance of the program.\r\nIf the enumeration operation has side effects, multiple enumerations might result in bugs.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1852},"Title":"Seal internal types","Category":"Performance","Description":"When a type isn\u0027t accessible outside its assembly and has no subtypes within its containing assembly, it can be safely sealed. Sealing types can improve performance.\r\nIf you apply System.Runtime.CompilerServices.InternalsVisibleToAttribute to the assembly that\u0027s being analyzed, this rule doesn\u0027t flag types that aren\u0027t marked as sealed by default, because a field may be used by a friend assembly. To analyze the assembly anyway, see Configure code to analyze.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1853},"Title":"Unnecessary call to \u0027Dictionary.ContainsKey(key)\u0027","Category":"Performance","Description":"There\u0027s no need to guard Dictionary.Remove(key) with Dictionary.ContainsKey(key). System.Collections.Generic.Dictionary%602.Remove(%600) already checks whether the key exists and doesn\u0027t throw if it doesn\u0027t exist.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1854},"Title":"Prefer the IDictionary.TryGetValue(TKey, out TValue) method","Category":"Performance","Description":"When an element of an IDictionary is accessed, the indexer implementation checks for a null value by calling the IDictionary.ContainsKey method. If you also call IDictionary.ContainsKey in an if clause to guard a value lookup, two lookups are performed when only one is needed.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1855},"Title":"Use Span\u003CT\u003E.Clear() instead of Span\u003CT\u003E.Fill()","Category":"Performance","Description":"It\u0027s more efficient to call System.Span%601.Clear than to call System.Span%601.Fill(%600) to fill the elements of the span with a default value.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1856},"Title":"Incorrect usage of ConstantExpected attribute","Category":"Performance","Description":"This rule flags incorrect uses of the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute, such as:\r\nThe System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Min or System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Max value isn\u0027t compatible with the parameter type.\r\n The parameter type isn\u0027t supported for the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute.\r\n The System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Min and System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Max values are inverted.\r\n The System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Min or System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Max value doesn\u0027t fit within the parameter value bounds.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1857},"Title":"The parameter expects a constant for optimal performance","Category":"Performance","Description":"This rule flags places in your code where you:\r\nImplement an inherited method that uses the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute but don\u0027t mark your parameter with System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.\r\n Pass a non-constant argument to a parameter that has the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute.\r\n Pass an invalid constant argument to a parameter that has the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute.\r\n Pass a constant argument to a parameter that has the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute attribute, and the argument is out of range of the System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Min or System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute.Max values.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1858},"Title":"Use StartsWith instead of IndexOf","Category":"Performance","Description":"It\u0027s more efficient and clearer to call System.String.StartsWith than to call System.String.IndexOf and compare the result with zero to determine whether a string starts with a given prefix.\r\nIndexOf searches the entire string, while StartsWith only compares at the beginning of the string.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1859},"Title":"Use concrete types when possible for improved performance","Category":"Performance","Description":"This rule recommends upgrading the type of specific local variables, fields, properties, method parameters, and method return types from interface or abstract\r\ntypes to concrete types when possible. Using concrete types leads to higher quality generated code by minimizing virtual or interface\r\ndispatch overhead and enabling inlining.\r\nThis rule only reports violations when there are virtual calls or interface calls that can actually be avoided by\r\nusing a concrete type.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1860},"Title":"Avoid using \u0027Enumerable.Any()\u0027 extension method","Category":"Performance","Description":"To determine whether a collection type has any elements, it\u0027s more efficient and clearer to use the Length, Count, or IsEmpty (if possible) properties than to call the System.Linq.Enumerable.Any method.\r\nAny(), which is an extension method, uses language integrated query (LINQ). It\u0027s more efficient to rely on the collection\u0027s own properties, and it also clarifies intent.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule is similar to CA1827: Do not use Count()/LongCount() when Any() can be used. However, that rule applies to the Linq Count() method, while this rule suggests using the Count property.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1861},"Title":"Avoid constant arrays as arguments","Category":"Performance","Description":"Constant arrays passed as arguments are not reused when called repeatedly, which implies a new array is created each time. If the passed array is not mutated within the called method, consider extracting it to a static readonly field to improve performance.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nIf the called method mutates the passed array or if you\u0027re not sure if the method would mutate the array, don\u0027t extract the array to a static readonly field. Doing so could be a breaking change. In this case, it\u0027s better to suppress the warning instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1862},"Title":"Use the \u0027StringComparison\u0027 method overloads to perform case-insensitive string comparisons","Category":"Performance","Description":"When code calls System.String.ToLower, System.String.ToLowerInvariant, System.String.ToUpper, or System.String.ToUpperInvariant, an allocation is performed. If the only reason for calling these methods is to perform a case-insensitive string comparison or search, the allocation is unnecessary. Instead, you can call a string comparison method that takes a System.StringComparison and specify one of the *IgnoreCase values.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1863},"Title":"Use CompositeFormat","Category":"Performance","Description":"It\u0027s expensive to parse a format string at run time. This rule locates places in your code where you can cache and use a System.Text.CompositeFormat instance as the argument to a formatting operation, rather than passing in the original format string. A System.Text.CompositeFormat instance parses the composite format string when it\u0027s created, which means the \u0022hot path\u0022 of string formatting can execute much faster.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1864},"Title":"Prefer the \u0027IDictionary.TryAdd(TKey, TValue)\u0027 method","Category":"Performance","Description":"Both System.Collections.Generic.Dictionary%602.ContainsKey(%600) and System.Collections.Generic.Dictionary%602.Add perform a lookup, which is redundant. System.Collections.Generic.Dictionary%602.Add also throws an exception if the key is already present in the dictionary. It\u0027s more efficient to call System.Collections.Generic.Dictionary%602.TryAdd, which returns a Boolean value that indicates if the value was added or not. TryAdd doesn\u0027t overwrite the key\u0027s value if the key is already present.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1865},"Title":"Use \u0027string.Method(char)\u0027 instead of \u0027string.Method(string)\u0027 for string with single char","Category":"Performance","Description":"The overload that takes a char parameter performs better than the overload that takes a string parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1866},"Title":"Use \u0027string.Method(char)\u0027 instead of \u0027string.Method(string)\u0027 for string with single char","Category":"Performance","Description":"The overload that takes a char parameter performs better than the overload that takes a string parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1867},"Title":"Use \u0027string.Method(char)\u0027 instead of \u0027string.Method(string)\u0027 for string with single char","Category":"Performance","Description":"The overload that takes a char parameter performs better than the overload that takes a string parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1868},"Title":"Unnecessary call to \u0027Contains\u0027 for sets","Category":"Performance","Description":"Both System.Collections.Generic.ISet%601.Add(%600) and System.Collections.Generic.ICollection%601.Remove(%600) perform a lookup, which makes it redundant to call System.Collections.Generic.ICollection%601.Contains(%600) beforehand. It\u0027s more efficient to call System.Collections.Generic.ISet%601.Add(%600) or System.Collections.Generic.ICollection%601.Remove(%600) directly, which returns a Boolean value indicating whether the item was added or removed.\r\nThis logic also applies to System.Collections.Immutable.IImmutableSet%601.Add(%600) and System.Collections.Immutable.IImmutableSet%601.Remove(%600), except that they either return a new set if the item is added or removed, or the original set if it wasn\u0027t.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1869},"Title":"Cache and reuse \u0027JsonSerializerOptions\u0027 instances","Category":"Performance","Description":"Using a local instance of System.Text.Json.JsonSerializerOptions for serialization or deserialization can substantially degrade the performance of your application if your code executes multiple times since System.Text.Json internally caches serialization-related metadata into the provided instance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1870},"Title":"Use a cached \u0027SearchValues\u0027 instance","Category":"Performance","Description":"Using a cached System.Buffers.SearchValues%601 instance is more efficient than passing values to IndexOfAny or ContainsAny directly.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1871},"Title":"Do not pass a nullable struct to \u0027ArgumentNullException.ThrowIfNull\u0027","Category":"Performance","Description":"For improved performance, it\u0027s better to check the HasValue property and manually throw an exception than to pass a nullable struct to ArgumentNullException.ThrowIfNull.","Options":[]},{"RuleId":{"RuleType":"CA","Id":1872},"Title":"Prefer \u0027Convert.ToHexString\u0027 and \u0027Convert.ToHexStringLower\u0027 over call chains based on \u0027BitConverter.ToString\u0027","Category":"Performance","Description":"Use System.Convert.ToHexString or System.Convert.ToHexStringLower when encoding bytes to a hexadecimal string representation. These methods are more efficient and allocation-friendly than using System.BitConverter.ToString in combination with System.String.Replace to remove dashes and System.String.ToLower.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2000},"Title":"Dispose objects before losing scope","Category":"Reliability","Description":"If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2002},"Title":"Do not lock on objects with weak identity","Category":"Reliability","Description":"An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object.\r\nThe following types have a weak identity and are flagged by the rule:\r\nSystem.String\r\n Arrays of value types, including integral types, floating-point types, and System.Boolean.\r\n System.MarshalByRefObject\r\n System.ExecutionEngineException\r\n System.OutOfMemoryException\r\n System.StackOverflowException\r\n System.Reflection.MemberInfo\r\n System.Reflection.ParameterInfo\r\n System.Threading.Thread\r\n this or Me object","Options":[]},{"RuleId":{"RuleType":"CA","Id":2007},"Title":"Do not directly await a Task","Category":"Reliability","Description":"When an asynchronous method awaits a System.Threading.Tasks.Task directly, continuation usually occurs in the same thread that created the task, depending on the async context. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling System.Threading.Tasks.Task.ConfigureAwait(System.Boolean) to signal your intention for continuation.","Options":["exclude_async_void_methods","output_kind"]},{"RuleId":{"RuleType":"CA","Id":2008},"Title":"Do not create tasks without passing a TaskScheduler","Category":"Reliability","Description":"The following .NET task creation and continuation methods have overloads that allow specifying or omitting a System.Threading.Tasks.TaskScheduler instance:\r\nSystem.Threading.Tasks.TaskFactory.StartNew methods\r\n System.Threading.Tasks.Task.ContinueWith methods\r\nAlways specify an explicit System.Threading.Tasks.TaskScheduler argument to avoid the default System.Threading.Tasks.TaskScheduler.Current%2A value, whose behavior is defined by the caller and may vary at run time. System.Threading.Tasks.TaskScheduler.Current%2A returns the scheduler associated with whatever System.Threading.Tasks.Task is currently running on that thread. If there is no such task, it returns System.Threading.Tasks.TaskScheduler.Default%2A, which represents the thread pool. Using System.Threading.Tasks.TaskScheduler.Current%2A could lead to deadlocks or UI responsiveness issues in some situations, when it was intended to create the task on the thread pool, but instead it waits to get back onto the UI thread.\r\nFor further information and detailed examples, see New TaskCreationOptions and TaskContinuationOptions in .NET Framework 4.5.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nVSTHRD105 - Avoid method overloads that assume TaskScheduler.Current is a similar rule implemented in Microsoft.VisualStudio.Threading.Analyzers package.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2009},"Title":"Do not call ToImmutableCollection on an ImmutableCollection value","Category":"Reliability","Description":"System.Collections.Immutable namespace contains types that define immutable collections. This rule analyzes the following immutable collection types:\r\nSystem.Collections.Immutable.ImmutableArray%601\r\n System.Collections.Immutable.ImmutableList%601\r\n System.Collections.Immutable.ImmutableHashSet%601\r\n System.Collections.Immutable.ImmutableSortedSet%601\r\n System.Collections.Immutable.ImmutableDictionary%602\r\n System.Collections.Immutable.ImmutableSortedDictionary%602\r\nThese types define extension methods that create a new immutable collection from an existing System.Collections.Generic.IEnumerable%601 collection.\r\nSystem.Collections.Immutable.ImmutableArray%601 defines System.Collections.Immutable.ImmutableArray.ToImmutableArray%2A.\r\n System.Collections.Immutable.ImmutableList%601 defines System.Collections.Immutable.ImmutableList.ToImmutableList%2A.\r\n System.Collections.Immutable.ImmutableHashSet%601 defines System.Collections.Immutable.ImmutableHashSet.ToImmutableHashSet%2A.\r\n System.Collections.Immutable.ImmutableSortedSet%601 defines System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet%2A.\r\n System.Collections.Immutable.ImmutableDictionary%602 defines System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary%2A.\r\n System.Collections.Immutable.ImmutableSortedDictionary%602 defines System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary%2A.\r\nThese extension methods are designed to convert a mutable collection to an immutable collection. However, the caller might accidentally pass in an immutable collection as input to these methods. This can represent a performance and/or a functional issue.\r\nPerformance issue: Unnecessary boxing, unboxing, and/or runtime type checks on an immutable collection.\r\n Potential functional issue: Caller assumed to be operating on a mutable collection, when it actually had an immutable collection.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2011},"Title":"Do not assign property within its setter","Category":"Reliability","Description":"Assigning a property to itself in its set accessor leads to an infinite chain of recursive calls to the set accessor. This results in a System.StackOverflowException at run time. Such a mistake is common when the property and the backing field to store the property value have similar names. Instead of assigning the value to the backing field, it was accidentally assigned to the property itself.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2012},"Title":"Use ValueTasks correctly","Category":"Reliability","Description":"System.Threading.Tasks.ValueTask instances returned from member invocations are intended to be directly awaited. Attempts to consume a ValueTask multiple times or to directly access one\u0027s result before it\u0027s known to be completed may result in an exception or corruption. Ignoring such a ValueTask is likely an indication of a functional bug and may degrade performance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2013},"Title":"Do not use ReferenceEquals with value types","Category":"Reliability","Description":"When comparing values using System.Object.ReferenceEquals%2A, if objA and objB are value types, they are boxed before they are passed to the System.Object.ReferenceEquals%2A method. This means that even if both objA and objB represent the same instance of a value type, the System.Object.ReferenceEquals%2A method nevertheless returns false, as the following example shows.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2014},"Title":"Do not use stackalloc in loops","Category":"Reliability","Description":"The C# stackalloc expression allocates memory from the current stack frame, and that memory may not be released until the current method call returns. If stackalloc is used in a loop, it can lead to stack overflows due to exhausting the stack memory.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2015},"Title":"Do not define finalizers for types derived from MemoryManager\u003CT\u003E","Category":"Reliability","Description":"Adding a finalizer to a type derived from System.Buffers.MemoryManager%601 is likely an indication of a bug, as it suggests a native resource that could have been handed out in a System.Span%601 is getting cleaned up and potentially while it is still in use by the System.Span%601.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThe System.Buffers.MemoryManager%601 class is intended for advanced scenarios. Most developers do not need to use it.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2016},"Title":"Forward the CancellationToken parameter to methods that take one","Category":"Reliability","Description":"This rule analyzes method definitions that take a CancellationToken as their last parameter, then analyzes all methods invoked in its body. If any of the method invocations can either accept a CancellationToken as the last parameter, or have an overload that takes a CancellationToken as the last parameter, then the rule suggests using that option instead to ensure that the cancellation notification gets propagated to all operations that can listen to it.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nRule CA2016 is available in all .NET versions where the CancellationToken type is available. For the applicable versions, see the CancellationToken \u0022Applies to\u0022 section.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2017},"Title":"Parameter count mismatch","Category":"Reliability","Description":"This rule flags logger calls that have an incorrect number of message arguments.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2018},"Title":"The count argument to Buffer.BlockCopy should specify the number of bytes to copy","Category":"Reliability","Description":"When using Buffer.BlockCopy, the count argument specifies the number of bytes to copy. You should only use Array.Length for the count argument on arrays whose elements are exactly one byte in size. byte, sbyte, and bool arrays have elements that are one byte in size.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2019},"Title":"ThreadStatic fields should not use inline initialization","Category":"Reliability","Description":"System.ThreadStaticAttribute fields should be initialized lazily on use and not with inline initialization or explicitly in a static (Shared in Visual Basic) constructor. A static constructor only initializes the field on the thread that runs the type\u0027s static constructor.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2020},"Title":"Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr","Category":"Reliability","Description":"With the numeric IntPtr feature, System.IntPtr and System.UIntPtr gained built-in operators for conversions, unary operations, and binary operations. These operators might throw when overflowing within checked context or may not throw in unchecked context compared to the previous user-defined operators in .NET 6 and earlier versions. You might encounter this behavioral change when upgrading to .NET 7.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2021},"Title":"Don\u0027t call Enumerable.Cast\u003CT\u003E or Enumerable.OfType\u003CT\u003E with incompatible types","Category":"Reliability","Description":"System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable) and System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable) require compatible types to produce the expected result:\r\nThe generic cast used by the sequence returned by System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable) throws an System.InvalidCastException at run time on elements of incompatible types.\r\n The generic type check used by System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable) won\u0027t succeed with elements of incompatible types, resulting in an empty sequence.\r\nWidening and user-defined conversions aren\u0027t supported with generic types.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2100},"Title":"Review SQL queries for security vulnerabilities","Category":"Security","Description":"This rule assumes that any string, whose value can\u0027t be determined at compile time, may contain user input. A SQL command string that is built from user input is vulnerable to SQL injection attacks. In a SQL injection attack, a malicious user supplies input that alters the design of a query in an attempt to damage or gain unauthorized access to the underlying database. Typical techniques include injection of a single quotation mark or apostrophe, which is the SQL literal string delimiter; two dashes, which signifies a SQL comment; and a semicolon, which indicates that a new command follows. If user input must be part of the query, use one of the following, listed in order of effectiveness, to reduce the risk of attack.\r\nUse a stored procedure.\r\n Use a parameterized command string.\r\n Validate the user input for both type and content before you build the command string.\r\nThe following .NET types implement the System.Data.IDbCommand.CommandText%2A property or provide constructors that set the property by using a string argument.\r\nSystem.Data.Odbc.OdbcCommand and System.Data.Odbc.OdbcDataAdapter\r\n System.Data.OleDb.OleDbCommand and System.Data.OleDb.OleDbDataAdapter\r\n System.Data.OracleClient.OracleCommand and System.Data.OracleClient.OracleDataAdapter\r\n System.Data.SqlClient.SqlCommand and System.Data.SqlClient.SqlDataAdapter\r\nIn some cases, this rule might not determine a string\u0027s value at compile time, even though you can. In those cases, this rule produces false positives when using those strings as SQL commands. The following is an example of such a string.\r\nint x = 10;\r\nstring query = \u0022SELECT TOP \u0022 \u002B x.ToString() \u002B \u0022 FROM Table\u0022;\r\nThe same applies when using ToString() implicitly.\r\nint x = 10;\r\nstring query = String.Format(\u0022SELECT TOP {0} FROM Table\u0022, x);","Options":[]},{"RuleId":{"RuleType":"CA","Id":2101},"Title":"Specify marshalling for P/Invoke string arguments","Category":"Globalization","Description":"When you convert from Unicode to ANSI, it is possible that not all Unicode characters can be represented in a specific ANSI code page. Best-fit mapping tries to solve this problem by substituting a character for the character that cannot be represented. The use of this feature can cause a potential security vulnerability because you cannot control the character that is chosen. For example, malicious code could intentionally create a Unicode string that contains characters that are not found in a particular code page, which are converted to file system special characters such as \u0027..\u0027 or \u0027/\u0027. Note also that security checks for special characters frequently occur before the string is converted to ANSI.\r\nBest-fit mapping is the default for the unmanaged conversion, WChar to MByte. Unless you explicitly disable best-fit mapping, your code might contain an exploitable security vulnerability because of this issue.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ECaution\u003C/p\u003E\r\nCode Access Security (CAS) should not be considered a security boundary.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2109},"Title":"Review visible event handlers","Category":"Security","Description":"An externally visible event-handling method presents a security issue that requires review.\r\nDo not expose event-handling methods unless absolutely necessary. An event handler, a delegate type, that invokes the exposed method can be added to any event as long as the handler and event signatures match. Events can potentially be raised by any code, and are frequently raised by highly trusted system code in response to user actions such as clicking a button. Adding a security check to an event-handling method does not prevent code from registering an event handler that invokes the method.\r\nA demand cannot reliably protect a method invoked by an event handler. Security demands help protect code from untrusted callers by examining the callers on the call stack. Code that adds an event handler to an event is not necessarily present on the call stack when the event handler\u0027s methods run. Therefore, the call stack might have only highly trusted callers when the event handler method is invoked. This causes demands made by the event handler method to succeed. Also, the demanded permission might be asserted when the method is invoked. For these reasons, the risk of not fixing a violation of this rule can only be assessed after reviewing the event-handling method. When you review your code, consider the following issues:\r\nDoes your event handler perform any operations that are dangerous or exploitable, such as asserting permissions or suppressing unmanaged code permission?\r\n What are the security threats to and from your code because it can run at any time with only highly trusted callers on the stack?","Options":[]},{"RuleId":{"RuleType":"CA","Id":2119},"Title":"Seal methods that satisfy private interfaces","Category":"Security","Description":"Interface methods have public accessibility, which cannot be changed by the implementing type. An internal interface creates a contract that is not intended to be implemented outside the assembly that defines the interface. A public type that implements a method of an internal interface using the virtual (Overridable in Visual Basic) modifier allows the method to be overridden by a derived type that is outside the assembly. If a second type in the defining assembly calls the method and expects an internal-only contract, behavior might be compromised when, instead, the overridden method in the outside assembly is executed. This creates a security vulnerability.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2153},"Title":"Avoid handling Corrupted State Exceptions","Category":"Security","Description":"CSE indicates that the state of a process has been corrupted and not caught by the system. In the corrupted state scenario, a general handler only catches the exception if you mark your method with the System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute attribute. By default, the Common Language Runtime (CLR) does not invoke catch handlers for CSEs.\r\nThe safest option is to allow the process to crash without catching these kinds of exceptions. Even logging code can allow attackers to exploit memory corruption bugs.\r\nThis warning triggers when catching CSEs with a general handler that catches all exceptions, for example, catch (System.Exception e) or catch with no exception parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2200},"Title":"Rethrow to preserve stack details","Category":"Usage","Description":"Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is rethrown by specifying the exception in the throw statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw statement without specifying the exception.\r\nIf you\u0027re rethrowing the exception from somewhere other than the handler (catch block), use System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception) to capture the exception in the handler and System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw when you want to rethrow it.\r\nFor more information, see Capture and rethrow exceptions properly.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2201},"Title":"Do not raise reserved exception types","Category":"Usage","Description":"The following exception types are too general to provide sufficient information to the user:\r\nSystem.Exception\r\n System.ApplicationException\r\n System.SystemException\r\nThe following exception types are reserved and should be thrown only by the common language runtime:\r\nSystem.AccessViolationException\r\n System.ExecutionEngineException\r\n System.IndexOutOfRangeException\r\n System.NullReferenceException\r\n System.OutOfMemoryException\r\n System.Runtime.InteropServices.COMException\r\n System.Runtime.InteropServices.ExternalException\r\n System.Runtime.InteropServices.SEHException\r\n System.StackOverflowException\r\nDon\u0027t throw general exceptions\r\nIf you throw a general exception type, such as System.Exception or System.SystemException, in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they don\u0027t know how to handle.\r\nInstead, either throw a more derived type that already exists in the framework, or create your own type that derives from System.Exception.\r\nThrow specific exceptions\r\nThe following table shows which exception to throw for various types of invalid arguments, including the value parameter in the set accessor of a property.\r\nInvalid argument Exception null reference System.ArgumentNullException Outside the allowed range of values (such as an index for a collection or list) System.ArgumentOutOfRangeException Invalid enum value System.ComponentModel.InvalidEnumArgumentException Contains a format that doesn\u0027t meet the parameter specifications of a method (such as the format string for ToString(String)) System.FormatException Otherwise invalid System.ArgumentException\r\nThe following table shows which exception to throw for various types of invalid operations.\r\nInvalid operation Exception Operation is invalid for the current state of an object. System.InvalidOperationException Operation is performed on an object that has been disposed. System.ObjectDisposedException Operation is not supported (such as in an overridden Stream.Write in a stream opened for reading). System.NotSupportedException Conversion would result in an overflow (such as in an explicit cast operator overload). System.OverflowException\r\nFor all other situations, consider creating your own type that derives from System.Exception and throw that.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2207},"Title":"Initialize value type static fields inline","Category":"Usage","Description":"When a value-type is declared, it undergoes a default initialization where all value-type fields are set to zero and all reference-type fields are set to null (Nothing in Visual Basic). An explicit static constructor is only guaranteed to run before an instance constructor or static member of the type is called. Therefore, if the type is created without calling an instance constructor, the static constructor is not guaranteed to run.\r\nIf all static data is initialized inline and no explicit static constructor is declared, the C# and Visual Basic compilers add the beforefieldinit flag to the CIL class definition. The compilers also add a private static constructor that contains the static initialization code. This private static constructor is guaranteed to run before any static fields of the type are accessed.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2208},"Title":"Instantiate argument exceptions correctly","Category":"Usage","Description":"Instead of calling the default constructor, call one of the constructor overloads that allows a more meaningful exception message to be provided. The exception message should target the developer and clearly explain the error condition and how to correct or avoid the exception.\r\nThe signatures of the one and two string constructors of System.ArgumentException and its derived types are not consistent with respect to the position message and paramName parameters. Make sure these constructors are called with the correct string arguments. The signatures are as follows:\r\nArgumentException(string message)\r\n ArgumentException(string message, string paramName)\r\n ArgumentNullException(string paramName)\r\n ArgumentNullException(string paramName, string message)\r\n ArgumentOutOfRangeException(string paramName)\r\n ArgumentOutOfRangeException(string paramName, string message)\r\n DuplicateWaitObjectException(string parameterName)\r\n DuplicateWaitObjectException(string parameterName, string message)","Options":[]},{"RuleId":{"RuleType":"CA","Id":2211},"Title":"Non-constant fields should not be visible","Category":"Usage","Description":"Static fields that are neither constants nor read-only are not thread-safe. Access to such a field must be carefully controlled and requires advanced programming techniques for synchronizing access to the class object. Because these are difficult skills to learn, and testing such an object poses its own challenges, static fields are best used to store data that does not change. This rule applies to libraries; applications should not expose any fields.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2213},"Title":"Disposable fields should be disposed","Category":"Usage","Description":"A type is responsible for disposing of all its unmanaged resources. Rule CA2213 checks to see whether a disposable type (that is, one that implements System.IDisposable) T declares a field F that is an instance of a disposable type FT. For each field F that\u0027s assigned a locally created object within the methods or initializers of the containing type T, the rule attempts to locate a call to FT.Dispose. The rule searches the methods called by T.Dispose and one level lower (that is, the methods called by the methods called by T.Dispose).\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nOther than the special cases, rule CA2213 fires only for fields that are assigned a locally created disposable object within the containing type\u0027s methods and initializers. If the object is created or assigned outside of type T, the rule does not fire. This reduces noise for cases where the containing type doesn\u0027t own the responsibility for disposing of the object.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2214},"Title":"Do not call overridable methods in constructors","Category":"Usage","Description":"When a virtual method is called, the actual type that executes the method is not selected until run time. When a constructor calls a virtual method, it\u0027s possible that the constructor for the instance that invokes the method has not executed. This could lead to errors or unexpected behavior, if an overridden virtual method relies on initialization and other configuration in the constructor.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2215},"Title":"Dispose methods should call base class dispose","Category":"Usage","Description":"If a type inherits from a disposable type, it must call the System.IDisposable.Dispose%2A method of the base type from within its own System.IDisposable.Dispose%2A method. Calling the base type Dispose method ensures that any resources created by the base type are released.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2216},"Title":"Disposable types should declare finalizer","Category":"Usage","Description":"A violation of this rule is reported if the disposable type contains fields of the following types:\r\nSystem.IntPtr\r\n System.UIntPtr\r\n System.Runtime.InteropServices.HandleRef","Options":[]},{"RuleId":{"RuleType":"CA","Id":2217},"Title":"Do not mark enums with FlagsAttribute","Category":"Usage","Description":"An enumeration should have System.FlagsAttribute present only if each value defined in the enumeration is a power of two or a combination of defined values.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2218},"Title":"Override GetHashCode on overriding Equals","Category":"Usage","Description":"System.Object.GetHashCode%2A returns a value, based on the current instance, that\u0027s suited for hashing algorithms and data structures such as hash tables. Two objects that are the same type and are equal must return the same hash code to ensure that instances of the following types work correctly:\r\nSystem.Collections.Hashtable\r\n System.Collections.SortedList\r\n System.Collections.Generic.Dictionary%602\r\n System.Collections.Generic.SortedDictionary%602\r\n System.Collections.Generic.SortedList%602\r\n System.Collections.Specialized.HybridDictionary\r\n System.Collections.Specialized.ListDictionary\r\n System.Collections.Specialized.OrderedDictionary\r\n Types that implement System.Collections.Generic.IEqualityComparer%601\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule only applies to Visual Basic code. The C# compiler generates a separate warning, CS0659.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2219},"Title":"Do not raise exceptions in exception clauses","Category":"Usage","Description":"When an exception is raised in an exception clause, it greatly increases the difficulty of debugging.\r\nWhen an exception is raised in a finally or fault clause, the new exception hides the active exception, if present. This makes the original error hard to detect and debug.\r\nWhen an exception is raised in a filter clause, the runtime silently catches the exception, and causes the filter to evaluate to false. There is no way to tell the difference between the filter evaluating to false and an exception being throw from a filter. This makes it hard to detect and debug errors in the filter\u0027s logic.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2224},"Title":"Override Equals on overloading operator equals","Category":"Usage","Description":"The equality operator is intended to be a syntactically convenient way to access the functionality of the System.Object.Equals%2A method. If you implement the equality operator, its logic must be identical to that of System.Object.Equals%2A.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule only applies to Visual Basic code. The C# compiler generates a separate warning, CS0660.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2225},"Title":"Operator overloads have named alternates","Category":"Usage","Description":"Operator overloading allows the use of symbols to represent computations for a type. For example, a type that overloads the plus symbol \u002B for addition would typically have an alternative member named Add. The named alternative member provides access to the same functionality as the operator. It\u0027s provided for developers who program in languages that do not support overloaded operators.\r\nThis rule examines:\r\nImplicit and explicit cast operators in a type by checking for methods named To\u003Ctypename\u003E and From\u003Ctypename\u003E.\r\n The operators listed in the following table:\r\nC# Visual Basic C\u002B\u002B Alternate method name \u002B (binary) \u002B \u002B (binary) Add \u002B= \u002B= \u002B= Add \u0026 And \u0026 BitwiseAnd \u0026= And= \u0026= BitwiseAnd | Or | BitwiseOr |= Or= |= BitwiseOr -- N/A -- Decrement / / / Divide /= /= /= Divide == = == Equals ^ Xor ^ Xor ^= Xor= ^= Xor \u003E \u003E \u003E CompareTo or Compare \u003E= \u003E= \u003E= CompareTo or Compare \u002B\u002B N/A \u002B\u002B Increment != \u003C\u003E != Equals \u003C\u003C \u003C\u003C \u003C\u003C LeftShift \u003C\u003C= \u003C\u003C= \u003C\u003C= LeftShift \u003C \u003C \u003C CompareTo or Compare \u003C= \u003C= \u003C= CompareTo or Compare \u0026\u0026 N/A \u0026\u0026 LogicalAnd || N/A || LogicalOr ! N/A ! LogicalNot % Mod % Mod or Remainder %= N/A %= Mod * (binary) * * Multiply *= N/A *= Multiply ~ Not ~ OnesComplement \u003E\u003E \u003E\u003E \u003E\u003E RightShift \u003E\u003E= N/A \u003E\u003E= RightShift - (binary) - (binary) - (binary) Subtract -= N/A -= Subtract true IsTrue N/A IsTrue (Property) - (unary) N/A - Negate \u002B (unary) N/A \u002B Plus false IsFalse False IsTrue (Property)\r\n*N/A means the operator cannot be overloaded in the selected language.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nIn C#, when a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2226},"Title":"Operators should have symmetrical overloads","Category":"Usage","Description":"There are no circumstances where either equality or inequality is applicable to instances of a type, and the opposite operator is undefined. Types typically implement the inequality operator by returning the negated value of the equality operator.\r\nThe C# compiler issues an error for violations of this rule.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2227},"Title":"Collection properties should be read only","Category":"Usage","Description":"A writable collection property allows a user to replace the collection with a completely different collection. A read-only or init-only property stops the collection from being replaced, but still allows the individual members to be set. If replacing the collection is a goal, the preferred design pattern is to include a method to remove all the elements from the collection, and a method to repopulate the collection. See the System.Collections.ArrayList.Clear%2A and System.Collections.ArrayList.AddRange%2A methods of the System.Collections.ArrayList class for an example of this pattern.\r\nBoth binary and XML serialization support read-only properties that are collections. The System.Xml.Serialization.XmlSerializer class has specific requirements for types that implement System.Collections.ICollection and System.Collections.IEnumerable in order to be serializable.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2229},"Title":"Implement serialization constructors","Category":"Usage","Description":"This rule is relevant for types that support custom serialization. A type supports custom serialization if it implements the System.Runtime.Serialization.ISerializable interface. The serialization constructor is required to deserialize, or recreate, objects that have been serialized using the System.Runtime.Serialization.ISerializable.GetObjectData method.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2231},"Title":"Overload operator equals on overriding ValueType.Equals","Category":"Usage","Description":"In most programming languages, there is no default implementation of the equality operator (==) for value types. If your programming language supports operator overloads, you should consider implementing the equality operator. Its behavior should be identical to that of System.Object.Equals%2A.\r\nYou cannot use the default equality operator in an overloaded implementation of the equality operator. Doing so will cause a stack overflow. To implement the equality operator, use the Object.Equals method in your implementation. For example:\r\nIf (Object.ReferenceEquals(left, Nothing)) Then\r\n Return Object.ReferenceEquals(right, Nothing)\r\nElse\r\n Return left.Equals(right)\r\nEnd If\r\nif (Object.ReferenceEquals(left, null))\r\n return Object.ReferenceEquals(right, null);\r\nreturn left.Equals(right);","Options":[]},{"RuleId":{"RuleType":"CA","Id":2234},"Title":"Pass System.Uri objects instead of strings","Category":"Usage","Description":"A parameter name is split into tokens based on the camel casing convention, and then each token is checked to see whether it equals \u0022uri\u0022, \u0022Uri\u0022, \u0022urn\u0022, \u0022Urn\u0022, \u0022url\u0022, or \u0022Url\u0022. If there is a match, the parameter is assumed to represent a uniform resource identifier (URI). A string representation of a URI is prone to parsing and encoding errors, and can lead to security vulnerabilities. The System.Uri class provides these services in a safe and secure manner. When there is a choice between two overloads that differ only regarding the representation of a URI, the user should choose the overload that takes a System.Uri argument.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2235},"Title":"Mark all non-serializable fields","Category":"Usage","Description":"A serializable type is one that is marked with the System.SerializableAttribute attribute. When the type is serialized, a System.Runtime.Serialization.SerializationException exception is thrown if the type contains an instance field of a type that\u0027s not serializable and doesn\u0027t implement the System.Runtime.Serialization.ISerializable interface.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ETip\u003C/p\u003E\r\nCA2235 does not fire for instance fields of types that implement System.Runtime.Serialization.ISerializable because they provide their own serialization logic.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2237},"Title":"Mark ISerializable types with SerializableAttribute","Category":"Usage","Description":"To be recognized by the common language runtime as serializable, types must be marked with the System.SerializableAttribute attribute even if the type uses a custom serialization routine through implementation of the System.Runtime.Serialization.ISerializable interface.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2241},"Title":"Provide correct arguments to formatting methods","Category":"Usage","Description":"The arguments to methods such as System.Console.WriteLine%2A, System.Console.Write%2A, and System.String.Format%2A consist of a format string followed by several System.Object instances. The format string consists of text and embedded format items of the form {index[,alignment][:formatString]}. \u0027index\u0027 is a zero-based integer that indicates which of the objects to format. If an object does not have a corresponding index in the format string, the object is ignored. If the object specified by \u0027index\u0027 does not exist, a System.FormatException is thrown at run time.","Options":["additional_string_formatting_methods"]},{"RuleId":{"RuleType":"CA","Id":2242},"Title":"Test for NaN correctly","Category":"Usage","Description":"System.Double.NaN, which represents a value that\u0027s not a number, results when an arithmetic operation is undefined. Any expression that tests for equality between a value and System.Double.NaN always returns false. Any expression that tests for inequality (!= in C#) between a value and System.Double.NaN always returns true.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2243},"Title":"Attribute string literals should parse correctly","Category":"Usage","Description":"Since attributes are derived from System.Attribute, and attributes are used at compile time, only constant values can be passed to their constructors. Attribute parameters that must represent URLs, GUIDs, and Versions cannot be typed as System.Uri, System.Guid, and System.Version, because these types cannot be represented as constants. Instead, they must be represented by strings.\r\nBecause the parameter is typed as a string, it is possible that an incorrectly formatted parameter could be passed at compile time.\r\nThis rule uses a naming heuristic to find parameters that represent a uniform resource identifier (URI), a Globally Unique Identifier (GUID), or a Version, and verifies that the passed value is correct.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2244},"Title":"Do not duplicate indexed element initializations","Category":"Usage","Description":"Object initializers let you assign values to any accessible fields or properties of an object at creation time without having to invoke a constructor followed by lines of assignment statements.\r\nIndexed element initializers in object initializers must initialize unique elements. A duplicate index will overwrite a previous element initialization.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2245},"Title":"Do not assign a property to itself","Category":"Usage","Description":"C# compiler generates a warning CS1717: Assignment made to same variable; did you mean to assign something else? when a field, local or parameter symbol is assigned to itself. Such a mistake is common when a local, parameter, or field symbol has a name similar to another symbol in scope. Instead of using different symbols on the left-hand and right-hand side of the assignment, the same symbol was used on both sides. This leads to a redundant assignment of the value to itself and generally indicates a functional bug.\r\nAssigning a property to itself is also a similar functional bug for almost all real world cases. However, in some extreme corner cases, fetching a property value can have side effects and the property\u0027s new value is different from the original value. If so, property self-assignment is not redundant and cannot be removed. This prevents the compiler from generating a CS1717 warning for property self-assignment, without introducing a breaking change for these cases.\r\nRule CA2245 aims at filling this gap. It reports the violation for property self-assignment to help fix these functional bugs. For the small set of corner cases where property self-assignment is desirable, CA2245 violations can be suppressed in source with an appropriate justification comment.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2246},"Title":"Do not assign a symbol and its member in the same statement","Category":"Usage","Description":"Assigning a symbol and its member, that is, a field or a property, in the same statement is not recommended. It is not clear if the member access was intended to use the symbol\u0027s old value prior to the assignment or the new value from the assignment in this statement. For clarity, the multi-assign statement must be split into two or more simple assignment statements.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2247},"Title":"Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum instead of TaskContinuationOptions enum","Category":"Usage","Description":"The TaskCompletionSource type has a constructor that accepts a System.Threading.Tasks.TaskCreationOptions enum value, and another constructor that accepts a System.Object. Accidentally passing a System.Threading.Tasks.TaskContinuationOptions enum value instead of a System.Threading.Tasks.TaskCreationOptions enum value will result in calling the System.Object-based constructor: it will compile and run, but it will not have the intended behavior.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2248},"Title":"Provide correct enum argument to Enum.HasFlag","Category":"Usage","Description":"The Enum.HasFlag method expects the enum argument to be of the same enum type as the instance on which the method is invoked. If these are different enum types, an unhandled exception will be thrown at run time.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2249},"Title":"Consider using String.Contains instead of String.IndexOf","Category":"Usage","Description":"When System.String.IndexOf%2A is used to check if the result is equal to -1 or greater or equal than 0, the call can be safely substituted with System.String.Contains%2A without an impact on performance.\r\nDepending on the System.String.IndexOf%2A overload being used, the suggested fix could get a comparisonType argument added:\r\nOverload Suggested fix String.IndexOf(char) String.Contains(char) String.IndexOf(string) String.Contains(string, StringComparison.CurrentCulture) String.IndexOf(char, StringComparison.Ordinal) String.Contains(char) String.IndexOf(string, StringComparison.Ordinal) String.Contains(string) String.IndexOf(char, NON StringComparison.Ordinal)* String.Contains(char, NON StringComparison.Ordinal)* String.IndexOf(string, NON StringComparison.Ordinal)* String.Contains(string, NON StringComparison.Ordinal)*\r\n* Any StringComparison enum value other than StringComparison.Ordinal:\r\nSystem.StringComparison.CurrentCulture\r\n System.StringComparison.CurrentCultureIgnoreCase\r\n System.StringComparison.InvariantCulture\r\n System.StringComparison.InvariantCultureIgnoreCase\r\n System.StringComparison.OrdinalIgnoreCase","Options":[]},{"RuleId":{"RuleType":"CA","Id":2250},"Title":"Use ThrowIfCancellationRequested","Category":"Usage","Description":"You can accomplish the same thing by calling System.Threading.CancellationToken.ThrowIfCancellationRequested.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2251},"Title":"Use String.Equals over String.Compare","Category":"Usage","Description":"System.String.Compare is designed to produce a total-order comparison that can be used for sorting. If you only care whether the strings are equal, it is both clearer and likely faster to use an equivalent overload of System.String.Equals.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2252},"Title":"Opt in to preview features before using them","Category":"Usage","Description":"When an API or assembly that\u0027s decorated with the System.Runtime.Versioning.RequiresPreviewFeaturesAttribute attribute is consumed, this rule checks if the call site has opted in to preview features. A call site has opted in to preview features if one of the following applies:\r\nIt is within the scope of a RequiresPreviewFeaturesAttribute annotation.\r\n It is part of an assembly or module that has already opted in to preview features.\r\nThe following image shows an example of the CA2252 diagnostic.\r\nCode editor with CA2252 warning.\r\nHere, Lib is a preview type that\u0027s constructed in the Main method. Main itself is not annotated as a preview method, so diagnostics are produced on the two constructors calls inside Main.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2253},"Title":"Named placeholders should not be numeric values","Category":"Usage","Description":"Named placeholders in the logging message template should not be comprised of only numeric characters.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2254},"Title":"Template should be a static expression","Category":"Usage","Description":"When performing logging, it\u0027s desirable to preserve the structure of the log (including placeholder names) along with the placeholder values. Preserving this information allows for better observability and search in log aggregation and monitoring software.\r\nPreferred:\r\nvar firstName = \u0022Lorenz\u0022;\r\nvar lastName = \u0022Otto\u0022;\r\n\r\n// This tells the logger that there are FirstName and LastName properties\r\n// on the log message, and correlates them with the argument values.\r\nlogger.Warning(\u0022Person {FirstName} {LastName} encountered an issue\u0022, firstName, lastName);\r\nNot preferred:\r\n// DO NOT DO THIS\r\n\r\nvar firstName = \u0022Lorenz\u0022;\r\nvar lastName = \u0022Otto\u0022;\r\n\r\n// Here, the log template itself is changing, and the association between named placeholders and their values is lost.\r\nlogger.Warning(\u0022Person \u0022 \u002B firstName \u002B \u0022 \u0022 \u002B lastName \u002B \u0022 encountered an issue\u0022);\r\n\r\n// String interpolation also loses the association between placeholder names and their values.\r\nlogger.Warning($\u0022Person {firstName} {lastName} encountered an issue\u0022);\r\nThe logging message template should not vary between calls.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2255},"Title":"The ModuleInitializer attribute should not be used in libraries","Category":"Usage","Description":"Module initializers are intended to be used by application code to ensure an application\u0027s components are initialized before the application code begins executing. If library code declares a method with the System.Runtime.CompilerServices.ModuleInitializerAttribute, it can interfere with application initialization and also lead to limitations in that application\u0027s trimming abilities. Library code should therefore not utilize the System.Runtime.CompilerServices.ModuleInitializerAttribute attribute.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2256},"Title":"All members declared in parent interfaces must have an implementation in a DynamicInterfaceCastableImplementation-attributed interface","Category":"Usage","Description":"Types attributed with System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute act as an interface implementation for a type that implements the IDynamicInterfaceCastable type. As a result, it must provide an implementation of all of the members defined in the inherited interfaces, because the type that implements IDynamicInterfaceCastable will not provide them otherwise.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2257},"Title":"Members defined on an interface with the \u0027DynamicInterfaceCastableImplementationAttribute\u0027 should be \u0027static\u0027","Category":"Usage","Description":"Since a type that implements IDynamicInterfaceCastable may not implement a dynamic interface in metadata, calls to an instance interface member that is not an explicit implementation defined on this type are likely to fail at run time. To avoid run-time errors, mark new interface members static.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2258},"Title":"Providing a \u0027DynamicInterfaceCastableImplementation\u0027 interface in Visual Basic is unsupported","Category":"Usage","Description":"Providing a functional interface that\u0027s attributed with DynamicInterfaceCastableImplementationAttribute requires the Default Interface Members feature, which is not supported in Visual Basic.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2259},"Title":"Ensure ThreadStatic is only used with static fields","Category":"Usage","Description":"System.ThreadStaticAttribute, which indicates that the value of a field is unique for each thread, only affects static (Shared in Visual Basic) fields. When applied to instance fields, the attribute has no impact on behavior.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2260},"Title":"Implement generic math interfaces correctly","Category":"Usage","Description":"Some generic math interfaces introduce static abstract members. The only way to access those static members is through a generic constraint that implements the \u0022curiously recurring template pattern\u0022 (CRTP). Therefore, the derived type itself must be used for the self-recurring type parameter. If a type implements such an interface without passing the required type parameter and CA2260 is ignored, the code will compile successfully but the static abstract will not be accessible. Thus, the type will not be usable. The compiler emits a warning with ID CS0315 on such usage.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2261},"Title":"Do not use ConfigureAwaitOptions.SuppressThrowing with Task\u003CTResult\u003E","Category":"Usage","Description":"The System.Threading.Tasks.ConfigureAwaitOptions.SuppressThrowing option isn\u0027t supported by the generic System.Threading.Tasks.Task%601, since that might lead to returning an invalid TResult. This rule flags the use of System.Threading.Tasks.ConfigureAwaitOptions.SuppressThrowing with System.Threading.Tasks.Task%601 to surface the error at build time rather than run time.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2262},"Title":"Set MaxResponseHeadersLength properly","Category":"Usage","Description":"The System.Net.Http.HttpClientHandler.MaxResponseHeadersLength property is measured in kilobytes, not bytes. The default maximum length is 64 KB, which should be large enough for a majority of use cases. If you set the property to a value greater than 128 kilobytes, it might be due to a misunderstanding of the units of this property.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2263},"Title":"Prefer generic overload when type is known","Category":"Usage","Description":"Generic overloads are preferable to overloads that accept an argument of type System.Type when the type is known at compile time (using the typeof operator in C# or the GetType operator in Visual Basic). Generic overloads promote cleaner and more type-safe code with improved compile-time checks.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2264},"Title":"Do not pass a non-nullable value to \u0027ArgumentNullException.ThrowIfNull\u0027","Category":"Usage","Description":"ArgumentNullException.ThrowIfNull throws when the passed argument is null. Certain constructs like non-nullable structs (except for System.Nullable%601), \u0027nameof()\u0027 expressions and \u0027new\u0027 expressions are known to never be null, so ArgumentNullException.ThrowIfNull will never throw.\r\nIn the case of a struct, since ArgumentNullException.ThrowIfNull accepts an object?, the struct is boxed, which causes an additional performance penalty.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2300},"Title":"Do not use insecure deserializer BinaryFormatter","Category":"Security","Description":"This rule finds System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserialization method calls or references. If you want to deserialize only when the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Binder property is set to restrict types, disable this rule and enable rules CA2301 and CA2302 instead. Limiting which types can be deserialized can help mitigate against known remote code execution attacks, but your deserialization will still be vulnerable to denial of service attacks.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2301},"Title":"Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder","Category":"Security","Description":"This rule finds System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserialization method calls or references, when System.Runtime.Serialization.Formatters.Binary.BinaryFormatter doesn\u0027t have its System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Binder set. If you want to disallow any deserialization with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter regardless of the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Binder property, disable this rule and CA2302, and enable rule CA2300.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2302},"Title":"Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize","Category":"Security","Description":"This rule finds System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserialization method calls or references when the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Binder might be null. If you want to disallow any deserialization with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter regardless of the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Binder property, disable this rule and CA2301, and enable rule CA2300.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2305},"Title":"Do not use insecure deserializer LosFormatter","Category":"Security","Description":"This rule finds System.Web.UI.LosFormatter deserialization method calls or references.\r\nLosFormatter is insecure and can\u0027t be made secure. For more information, see the BinaryFormatter security guide.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2310},"Title":"Do not use insecure deserializer NetDataContractSerializer","Category":"Security","Description":"This rule finds System.Runtime.Serialization.NetDataContractSerializer deserialization method calls or references. If you want to deserialize only when the System.Runtime.Serialization.NetDataContractSerializer.Binder property is set to restrict types, disable this rule and enable rules CA2311 and CA2312 instead. Limiting which types can be deserialized can help mitigate against known remote code execution attacks, but your deserialization will still be vulnerable to denial of service attacks.\r\nNetDataContractSerializer is insecure and can\u0027t be made secure. For more information, see the BinaryFormatter security guide.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2311},"Title":"Do not deserialize without first setting NetDataContractSerializer.Binder","Category":"Security","Description":"This rule finds System.Runtime.Serialization.NetDataContractSerializer deserialization method calls or references, when System.Runtime.Serialization.NetDataContractSerializer doesn\u0027t have its System.Runtime.Serialization.NetDataContractSerializer.Binder set. If you want to disallow any deserialization with System.Runtime.Serialization.NetDataContractSerializer regardless of the System.Runtime.Serialization.NetDataContractSerializer.Binder property, disable this rule and CA2312, and enable rule CA2310.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2312},"Title":"Ensure NetDataContractSerializer.Binder is set before deserializing","Category":"Security","Description":"This rule finds System.Runtime.Serialization.NetDataContractSerializer deserialization method calls or references when the System.Runtime.Serialization.NetDataContractSerializer.Binder might be null. If you want to disallow any deserialization with System.Runtime.Serialization.NetDataContractSerializer regardless of the System.Runtime.Serialization.NetDataContractSerializer.Binder property, disable this rule and CA2311, and enable rule CA2310.\r\nNetDataContractSerializer is insecure and can\u0027t be made secure. For more information, see the BinaryFormatter security guide.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2315},"Title":"Do not use insecure deserializer ObjectStateFormatter","Category":"Security","Description":"This rule finds System.Web.UI.ObjectStateFormatter deserialization method calls or references.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2321},"Title":"Do not deserialize with JavaScriptSerializer using a SimpleTypeResolver","Category":"Security","Description":"This rule finds System.Web.Script.Serialization.JavaScriptSerializer deserialization method calls or references, after initializing the System.Web.Script.Serialization.JavaScriptSerializer with a System.Web.Script.Serialization.SimpleTypeResolver.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2322},"Title":"Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing","Category":"Security","Description":"This rule finds System.Web.Script.Serialization.JavaScriptSerializer deserialization method calls or references, when the System.Web.Script.Serialization.JavaScriptSerializer may have been initialized with a System.Web.Script.Serialization.SimpleTypeResolver.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2326},"Title":"Do not use TypeNameHandling values other than None","Category":"Security","Description":"This rule finds Newtonsoft.Json.TypeNameHandling values other than None. If you want to deserialize only when a Newtonsoft.Json.Serialization.ISerializationBinder is specified to restrict deserialized types, disable this rule and enable rules CA2327, CA2328, CA2329, and CA2330 instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2327},"Title":"Do not use insecure JsonSerializerSettings","Category":"Security","Description":"This rule finds Newtonsoft.Json.JsonSerializerSettings instances that are configured to deserialize types specified from input, but not configured to restrict deserialized types with a Newtonsoft.Json.Serialization.ISerializationBinder. If you want to disallow deserialization of types specified from input completely, disable rules CA2327, CA2328, CA2329, and CA2330, and enable rule CA2326 instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2328},"Title":"Ensure that JsonSerializerSettings are secure","Category":"Security","Description":"This rule finds Newtonsoft.Json.JsonSerializerSettings instances that might be configured to deserialize types specified from input, but may not be configured to restrict deserialized types with a Newtonsoft.Json.Serialization.ISerializationBinder. If you want to disallow deserialization of types specified from input completely, disable rules CA2327, CA2328, CA2329, and CA2330, and enable rule CA2326 instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2329},"Title":"Do not deserialize with JsonSerializer using an insecure configuration","Category":"Security","Description":"This rule finds Newtonsoft.Json.JsonSerializer instances that are configured to deserialize types specified from input, but not configured to restrict deserialized types with a Newtonsoft.Json.Serialization.ISerializationBinder. If you want to disallow deserialization of types specified from input completely, disable rules CA2327, CA2328, CA2329, and CA2330, and enable rule CA2326 instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2330},"Title":"Ensure that JsonSerializer has a secure configuration when deserializing","Category":"Security","Description":"This rule finds Newtonsoft.Json.JsonSerializer instances that might be configured to deserialize types specified from input, but may not be configured to restrict deserialized types with a Newtonsoft.Json.Serialization.ISerializationBinder. If you want to disallow deserialization of types specified from input completely, disable rules CA2327, CA2328, CA2329, and CA2330, and enable rule CA2326 instead.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2350},"Title":"Ensure DataTable.ReadXml()\u0027s input is trusted","Category":"Security","Description":"When deserializing a System.Data.DataTable with untrusted input, an attacker can craft malicious input to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2351},"Title":"Ensure DataSet.ReadXml()\u0027s input is trusted","Category":"Security","Description":"When deserializing a System.Data.DataSet with untrusted input, an attacker can craft malicious input to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2352},"Title":"Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks","Category":"Security","Description":"When deserializing untrusted input with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a remote code execution attack.\r\nThis rule finds types which are insecure when deserialized. If your code doesn\u0027t deserialize the types found, then you don\u0027t have a deserialization vulnerability.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2353},"Title":"Unsafe DataSet or DataTable in serializable type","Category":"Security","Description":"When deserializing untrusted input and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nThis rule finds types which are insecure when deserialized. If your code doesn\u0027t deserialize the types found, then you don\u0027t have a deserialization vulnerability.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2354},"Title":"Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attack","Category":"Security","Description":"When deserializing untrusted input with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a remote code execution attack.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2355},"Title":"Unsafe DataSet or DataTable in deserialized object graph","Category":"Security","Description":"When deserializing untrusted input with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2356},"Title":"Unsafe DataSet or DataTable type in web deserialized object graph","Category":"Security","Description":"When deserializing untrusted input and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2361},"Title":"Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data","Category":"Security","Description":"When deserializing a System.Data.DataSet with untrusted input, an attacker can craft malicious input to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.\r\nThis rule is like CA2351, but for autogenerated code for an in-memory representation of data within a GUI application. Usually, these autogenerated classes aren\u0027t deserialized from untrusted input. Your application\u0027s usage may vary.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":2362},"Title":"Unsafe DataSet or DataTable in autogenerated serializable type can be vulnerable to remote code execution attacks","Category":"Security","Description":"When deserializing untrusted input with System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and the deserialized object graph contains a System.Data.DataSet or System.Data.DataTable, an attacker can craft a malicious payload to perform a remote code execution attack.\r\nThis rule is like CA2352, but for autogenerated code for an in-memory representation of data within a GUI application. Usually, these autogenerated classes aren\u0027t deserialized from untrusted input. Your application\u0027s usage may vary.\r\nThis rule finds types which are insecure when deserialized. If your code doesn\u0027t deserialize the types found, then you don\u0027t have a deserialization vulnerability.\r\nFor more information, see DataSet and DataTable security guidance.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3001},"Title":"Review code for SQL injection vulnerabilities","Category":"Security","Description":"When working with untrusted input and SQL commands, be mindful of SQL injection attacks. An SQL injection attack can execute malicious SQL commands, compromising the security and integrity of your application. Typical techniques include using a single quotation mark or apostrophe for delimiting literal strings, two dashes for a comment, and a semicolon for the end of a statement. For more information, see SQL Injection.\r\nThis rule attempts to find input from HTTP requests reaching an SQL command\u0027s text.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that executes the SQL command, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3002},"Title":"Review code for XSS vulnerabilities","Category":"Security","Description":"When working with untrusted input from web requests, be mindful of cross-site scripting (XSS) attacks. An XSS attack injects untrusted input into raw HTML output, allowing the attacker to execute malicious scripts or maliciously modify content in your web page. A typical technique is putting \u003Cscript\u003E elements with malicious code in input. For more information, see OWASP\u0027s XSS.\r\nThis rule attempts to find input from HTTP requests reaching raw HTML output.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that outputs raw HTML, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3003},"Title":"Review code for file path injection vulnerabilities","Category":"Security","Description":"When working with untrusted input from web requests, be mindful of using user-controlled input when specifying paths to files. An attacker may be able to read an unintended file, resulting in information disclosure of sensitive data. Or, an attacker may be able to write to an unintended file, resulting in unauthorized modification of sensitive data or compromising the server\u0027s security. A common attacker technique is Path Traversal to access files outside of the intended directory.\r\nThis rule attempts to find input from HTTP requests reaching a path in a file operation.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that writes to a file, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3004},"Title":"Review code for information disclosure vulnerabilities","Category":"Security","Description":"Disclosing exception information gives attackers insight into the internals of your application, which can help attackers find other vulnerabilities to exploit.\r\nThis rule attempts to find an exception message, stack trace, or string representation being output to an HTTP response.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly catches an exception and then passes it to another assembly that outputs the exception, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. For information about how to configure the limit in an EditorConfig file, see Analyzer Configuration.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3005},"Title":"Review code for LDAP injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of Lightweight Directory Access Protocol (LDAP) injection attacks. An attacker can potentially run malicious LDAP statements against information directories. Applications that use user input to construct dynamic LDAP statements to access directory services are particularly vulnerable.\r\nThis rule attempts to find input from HTTP requests reaching an LDAP statement.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that executes an LDAP statement, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3006},"Title":"Review code for process command injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of command injection attacks. A command injection attack can execute malicious commands on the underlying operating system, compromising the security and integrity of your server.\r\nThis rule attempts to find input from HTTP requests reaching a process command.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that starts a process, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3007},"Title":"Review code for open redirect vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of open redirect vulnerabilities. An attacker can exploit an open redirect vulnerability to use your website to give the appearance of a legitimate URL, but redirect an unsuspecting visitor to a phishing or other malicious webpage.\r\nThis rule attempts to find input from HTTP requests reaching an HTTP redirect URL.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that responds with an HTTP redirect, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3008},"Title":"Review code for XPath injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of XPath injection attacks. Constructing XPath queries using untrusted input may allow an attacker to maliciously manipulate the query to return an unintended result, and possibly disclose the contents of the queried XML.\r\nThis rule attempts to find input from HTTP requests reaching an XPath expression.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that performs an XPath query, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3009},"Title":"Review code for XML injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of XML injection attacks. An attacker can use XML injection to insert special characters into an XML document, making the document invalid XML. Or, an attacker could maliciously insert XML nodes of their choosing.\r\nThis rule attempts to find input from HTTP requests reaching a raw XML write.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that writes raw XML, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3010},"Title":"Review code for XAML injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of XAML injection attacks. XAML is a markup language that directly represents object instantiation and execution. That means elements created in XAML can interact with system resources (for example, network access and file system IO). If an attacker can control the input to a System.Windows.Markup.XamlReader Load method call, then the attacker can execute code.\r\nThis rule attempts to find input from HTTP requests that reaches a System.Windows.Markup.XamlReader Load method.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that loads XAML, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3011},"Title":"Review code for DLL injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of loading untrusted code. If your web application loads untrusted code, an attacker may be able to inject malicious DLLs into your process and execute malicious code.\r\nThis rule attempts to find input from an HTTP request that reaches a method that loads an assembly.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that loads an assembly, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3012},"Title":"Review code for regex injection vulnerabilities","Category":"Security","Description":"When working with untrusted input, be mindful of regex injection attacks. An attacker can use regex injection to maliciously modify a regular expression, to make the regex match unintended results, or to make the regex consume excessive CPU resulting in a Denial of Service attack.\r\nThis rule attempts to find input from HTTP requests reaching a regular expression.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule can\u0027t track data across assemblies. For example, if one assembly reads the HTTP request input and then passes it to another assembly that creates a regular expression, this rule won\u0027t produce a warning.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThere is a configurable limit to how deep this rule will analyze data flow across method calls. See Analyzer Configuration for how to configure the limit in an EditorConfig file.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3061},"Title":"Do not add schema by URL","Category":"Security","Description":"Do not use the unsafe overload of the Add method because it may cause dangerous external references.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3075},"Title":"Insecure DTD Processing","Category":"Security","Description":"A Document Type Definition (DTD) is one of two ways an XML parser can determine the validity of a document, as defined by the World Wide Web Consortium (W3C) Extensible Markup Language (XML) 1.0. This rule seeks properties and instances where untrusted data is accepted to warn developers about potential Information Disclosure threats or Denial of Service (DoS) attacks. This rule triggers when:\r\nDtdProcessing is enabled on the System.Xml.XmlReader instance, which resolves external XML entities using System.Xml.XmlUrlResolver.\r\n The System.Xml.XmlNode.InnerXml%2A property in the XML is set.\r\n System.Xml.XmlReaderSettings.DtdProcessing%2A property is set to Parse.\r\n Untrusted input is processed using System.Xml.XmlResolver instead of System.Xml.XmlSecureResolver.\r\n The System.Xml.XmlReader.Create method is invoked with an insecure System.Xml.XmlReaderSettings instance or no instance at all.\r\n System.Xml.XmlReader is created with insecure default settings or values.\r\nIn each of these cases, the outcome is the same: the contents from either the file system or network shares from the machine where the XML is processed will be exposed to the attacker, or DTD processing can be used as a DoS vector.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3076},"Title":"Insecure XSLT Script Execution","Category":"Security","Description":"XSLT is a World Wide Web Consortium (W3C) standard for transforming XML data. XSLT is typically used to write style sheets to transform XML data to other formats such as HTML, fixed-length text, comma-separated text, or a different XML format. Although prohibited by default, you may choose to enable it for your project.\r\nTo ensure you\u0027re not exposing an attack surface, this rule triggers whenever the XslCompiledTransform.System.Xml.Xsl.XslCompiledTransform.Load%2A receives insecure combination instances of System.Xml.Xsl.XsltSettings and System.Xml.XmlResolver, which allows malicious script processing.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3077},"Title":"Insecure Processing in API Design, XML Document and XML Text Reader","Category":"Security","Description":"A Document Type Definition (DTD) is one of two ways an XML parser can determine the validity of a document, as defined by the World Wide Web Consortium (W3C) Extensible Markup Language (XML) 1.0. This rule seeks properties and instances where untrusted data is accepted to warn developers about potential Information Disclosure threats, which may lead to Denial of Service (DoS) attacks. This rule triggers when:\r\nSystem.Xml.XmlDocument or System.Xml.XmlTextReader classes use default resolver values for DTD processing .\r\n No constructor is defined for the XmlDocument or XmlTextReader derived classes or no secure value is used for System.Xml.XmlResolver.","Options":[]},{"RuleId":{"RuleType":"CA","Id":3147},"Title":"Mark verb handlers with ValidateAntiForgeryToken","Category":"Security","Description":"When designing an ASP.NET MVC controller, be mindful of cross-site request forgery attacks. A cross-site request forgery attack can send malicious requests from an authenticated user to your ASP.NET MVC controller. For more information, see XSRF/CSRF prevention in ASP.NET MVC and web pages.\r\nThis rule checks that ASP.NET MVC controller action methods either:\r\nHave the ValidateAntiforgeryTokenAttribute and specify allowed HTTP verbs, not including HTTP GET.\r\n Specify HTTP GET as an allowed verb.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5350},"Title":"Do Not Use Weak Cryptographic Algorithms","Category":"Security","Description":"Weak encryption algorithms and hashing functions are used today for a number of reasons, but they should not be used to guarantee the confidentiality of the data they protect.\r\nThe rule triggers when it finds 3DES, SHA1 or RIPEMD160 algorithms in the code and throws a warning to the user.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5351},"Title":"Do Not Use Broken Cryptographic Algorithms","Category":"Security","Description":"Broken cryptographic algorithms are not considered secure and their use should be discouraged. The MD5 hash algorithm is susceptible to known collision attacks, though the specific vulnerability will vary based on the context of use. Hashing algorithms used to ensure data integrity (for example, file signature or digital certificate) are particularly vulnerable. In this context, attackers could generate two separate pieces of data, such that benign data can be substituted with malicious data, without changing the hash value or invalidating an associated digital signature.\r\nFor encryption algorithms:\r\nSystem.Security.Cryptography.DES encryption contains a small key size, which could be brute-forced in less than a day.\r\n System.Security.Cryptography.RC2 encryption is susceptible to a related-key attack, where the attacker finds mathematical relationships between all key values.\r\nThis rule triggers when it finds any of the above cryptographic functions in source code and throws a warning to the user.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5358},"Title":"Do Not Use Unsafe Cipher Modes","Category":"Security","Description":"These modes are vulnerable to attacks and may cause exposure of sensitive information. For example, using ECB to encrypt a plaintext block always produces a same cipher text, so it can easily tell if two encrypted messages are identical. Using approved modes can avoid these unnecessary risks.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5359},"Title":"Do not disable certificate validation","Category":"Security","Description":"A certificate can help authenticate the identity of the server. Clients should validate the server certificate to ensure requests are sent to the intended server. If the System.Net.ServicePointManager.ServerCertificateValidationCallback always returns true, then by default any certificate will pass validation for all outgoing HTTPS requests.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5360},"Title":"Do not call dangerous methods in deserialization","Category":"Security","Description":"Insecure deserialization is a vulnerability which occurs when untrusted data is used to abuse the logic of an application, inflict a Denial-of-Service (DoS) attack, or even execute arbitrary code upon it being deserialized. It\u0027s frequently possible for malicious users to abuse these deserialization features when the application is deserializing untrusted data which is under their control. Specifically, invoke dangerous methods in the process of deserialization. Successful insecure deserialization attacks could allow an attacker to carry out attacks such as DoS attacks, authentication bypasses, and remote code execution.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5361},"Title":"Do not disable SChannel use of strong crypto","Category":"Security","Description":"Setting Switch.System.Net.DontEnableSchUseStrongCrypto to true weakens the cryptography used in outgoing Transport Layer Security (TLS) connections. Weaker cryptography can compromise the confidentiality of communication between your application and the server, making it easier for attackers to eavesdrop sensitive data. For more information, see Transport Layer Security (TLS) best practices with .NET Framework.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5362},"Title":"Potential reference cycle in deserialized object graph","Category":"Security","Description":"If deserializing untrusted data, then any code processing the deserialized object graph needs to handle reference cycles without going into infinite loops. This includes both code that\u0027s part of a deserialization callback and code that processes the object graph after deserialization completed. Otherwise, an attacker could perform a Denial-of-Service attack with malicious data containing a reference cycle.\r\nThis rule doesn\u0027t necessarily mean there\u0027s a vulnerability, but just flags potential reference cycles in deserialized object graphs.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5363},"Title":"Do not disable request validation","Category":"Security","Description":"Request validation is a feature in ASP.NET that examines HTTP requests and determines whether they contain potentially dangerous content that can lead to injection attacks, including cross-site-scripting.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5364},"Title":"Do not use deprecated security protocols","Category":"Security","Description":"Transport Layer Security (TLS) secures communication between computers, most commonly with Hypertext Transfer Protocol Secure (HTTPS). Older protocol versions of TLS are less secure than TLS 1.2 and TLS 1.3 and are more likely to have new vulnerabilities. Avoid older protocol versions to minimize risk. For guidance on identifying and removing deprecated protocol versions, see Solving the TLS 1.0 Problem, 2nd Edition.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5365},"Title":"Do Not Disable HTTP Header Checking","Category":"Security","Description":"HTTP header checking enables encoding of the carriage return and newline characters, \\r and \\n, that are found in response headers. This encoding can help to avoid injection attacks that exploit an application that echoes untrusted data contained in the header.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5366},"Title":"Use XmlReader For DataSet Read XML","Category":"Security","Description":"Using a System.Data.DataSet to read XML with untrusted data may load dangerous external references, which should be restricted by using an System.Xml.XmlReader with a secure resolver or with DTD processing disabled.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5367},"Title":"Do not serialize types with pointer fields","Category":"Security","Description":"This rule checks whether there???s a serializable class with a pointer field or property. Members that can???t be serialized can be a pointer, such as static members or fields marked with System.NonSerializedAttribute.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5368},"Title":"Set ViewStateUserKey For Classes Derived From Page","Category":"Security","Description":"When designing an ASP.NET Web Form, be mindful of cross-site request forgery (CSRF) attacks. A CSRF attack can send malicious requests from an authenticated user to your ASP.NET Web Form.\r\nOne way of protecting against CSRF attacks in ASP.NET Web Form is by setting a page\u0027s System.Web.UI.Page.ViewStateUserKey to a string that is unpredictable and unique to a session. For more information, see Take Advantage of ASP.NET Built-in Features to Fend Off Web Attacks.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5369},"Title":"Use XmlReader for Deserialize","Category":"Security","Description":"Processing untrusted DTD and XML schemas may enable loading dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD and XML inline schema processing disabled. This rule detects code that uses the System.Xml.Serialization.XmlSerializer.Deserialize method and does not take XmlReader as a constructor parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5370},"Title":"Use XmlReader for validating reader","Category":"Security","Description":"Processing untrusted DTD and XML schemas may enable loading dangerous external references. This dangerous loading can be restricted by using an XmlReader with a secure resolver or with DTD and XML inline schema processing disabled. This rule detects code that uses the XmlValidatingReader class without XmlReader as a constructor parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5371},"Title":"Use XmlReader for schema read","Category":"Security","Description":"Processing untrusted DTD and XML schemas may enable loading dangerous external references. Using an XmlReader with a secure resolver or with DTD and XML inline schema processing disabled restricts this. This rule detects code that uses the System.Xml.Schema.XmlSchema.Read method without XmlReader as a parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5372},"Title":"Use XmlReader for XPathDocument","Category":"Security","Description":"Processing XML from untrusted data may load dangerous external references, which can be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. This rule detects code that uses the XPathDocument class and doesn???t take XmlReader as a constructor parameter.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5373},"Title":"Do not use obsolete key derivation function","Category":"Security","Description":"This rule detects the invocation of weak key derivation methods System.Security.Cryptography.PasswordDeriveBytes and System.Security.Cryptography.Rfc2898DeriveBytes.CryptDeriveKey.\r\nSystem.Security.Cryptography.PasswordDeriveBytes used a weak algorithm PBKDF1. System.Security.Cryptography.Rfc2898DeriveBytes.CryptDeriveKey does not use iteration count and salt from the Rfc2898DeriveBytes object, which makes it weak.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5374},"Title":"Do not use XslTransform","Category":"Security","Description":"System.Xml.Xsl.XslTransform is vulnerable when operating on untrusted input. An attack could execute arbitrary code.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5375},"Title":"Do not use account shared access signature","Category":"Security","Description":"An account SAS can delegate access to read, write, and delete operations on blob containers, tables, queues, and file shares that are not permitted with a service SAS. However, it doesn\u0027t support container-level policies and has less flexibility and control over the permissions that are granted. If possible, use a service SAS for fine grained access control. For more information, see Delegate access with a shared access signature.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5376},"Title":"Use SharedAccessProtocol HttpsOnly","Category":"Security","Description":"SAS is a sensitive data which can\u0027t be transported in plain text on HTTP.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5377},"Title":"Use container level access policy","Category":"Security","Description":"A container-level access policy can be modified or revoked at any time. It provides greater flexibility and control over the permissions that are granted. For more information, see Define a stored access policy.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5378},"Title":"Do not disable ServicePointManagerSecurityProtocols","Category":"Security","Description":"Setting Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols to true limits Windows Communication Framework\u0027s (WCF) Transport Layer Security (TLS) connections to using TLS 1.0. That version of TLS will be deprecated. For more information, see Transport Layer Security (TLS) best practices with .NET Framework.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5379},"Title":"Ensure key derivation function algorithm is sufficiently strong","Category":"Security","Description":"The System.Security.Cryptography.Rfc2898DeriveBytes class defaults to using the System.Security.Cryptography.HashAlgorithmName.SHA1 algorithm. When instantiating an System.Security.Cryptography.Rfc2898DeriveBytes object, you should specify a hash algorithm of System.Security.Cryptography.HashAlgorithmName.SHA256 or higher. Note that System.Security.Cryptography.Rfc2898DeriveBytes.HashAlgorithm property only has a get accessor.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5380},"Title":"Do not add certificates to root store","Category":"Security","Description":"This rule detects code that adds a certificate into the Trusted Root Certification Authorities certificate store. By default, the Trusted Root Certification Authorities certificate store is configured with a set of public CAs that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root certification authorities (CA\u0027s) can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack ??? and a single vulnerable, malicious or coercible CA undermines the security of the entire system.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5381},"Title":"Ensure certificates are not added to root store","Category":"Security","Description":"This rule detects code that potentially adds a certificate into the Trusted Root Certification Authorities certificate store. By default, the Trusted Root Certification Authorities certificate store is configured with a set of public certification authorities (CAs) that has met the requirements of the Microsoft Root Certificate Program. Since all trusted root CAs can issue certificates for any domain, an attacker can pick a weak or coercible CA that you install by yourself to target for an attack ??? and a single vulnerable, malicious or coercible CA undermines the security of the entire system.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5382},"Title":"Use secure cookies in ASP.NET Core","Category":"Security","Description":"Applications available over HTTPS must use secure cookies, which indicate to the browser that the cookie should only be transmitted using Transport Layer Security (TLS).","Options":[]},{"RuleId":{"RuleType":"CA","Id":5383},"Title":"Ensure use secure cookies in ASP.NET Core","Category":"Security","Description":"Applications available over HTTPS must use secure cookies, which indicate to the browser that the cookie should only be transmitted using Transport Layer Security (TLS).","Options":[]},{"RuleId":{"RuleType":"CA","Id":5384},"Title":"Do not use digital signature algorithm (DSA)","Category":"Security","Description":"DSA is a weak asymmetric encryption algorithm.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5385},"Title":"Use Rivest???Shamir???Adleman (RSA) algorithm with sufficient key size","Category":"Security","Description":"An RSA key smaller than 2048 bits is more vulnerable to brute force attacks.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5386},"Title":"Avoid hardcoding SecurityProtocolType value","Category":"Security","Description":"Transport Layer Security (TLS) secures communication between computers, most commonly with Hypertext Transfer Protocol Secure (HTTPS). Protocol versions TLS 1.0 and TLS 1.1 are deprecated, while TLS 1.2 and TLS 1.3 are current. In the future, TLS 1.2 and TLS 1.3 may be deprecated. To ensure that your application remains secure, avoid hardcoding a protocol version and target at least .NET Framework v4.7.1. For more information, see Transport Layer Security (TLS) best practices with .NET Framework.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5387},"Title":"Do not use weak key derivation function with insufficient iteration count","Category":"Security","Description":"This rule checks if a cryptographic key was generated by System.Security.Cryptography.Rfc2898DeriveBytes with an iteration count of less than 100,000. A higher iteration count can help mitigate against dictionary attacks that try to guess the generated cryptographic key.\r\nThis rule is similar to CA5388, but analysis determines that the iteration count is less than 100,000.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5388},"Title":"Ensure sufficient iteration count when using weak key derivation function","Category":"Security","Description":"This rule checks if a cryptographic key was generated by System.Security.Cryptography.Rfc2898DeriveBytes with an iteration count that may be less than 100,000. A higher iteration count can help mitigate against dictionary attacks that try to guess the generated cryptographic key.\r\nThis rule is similar to CA5387, but analysis can\u0027t determine if the iteration count is less than 100,000.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5389},"Title":"Do not add archive item\u0027s path to the target file system path","Category":"Security","Description":"File path can be relative and can lead to file system access outside of the expected file system target path, leading to malicious config changes and remote code execution via lay-and-wait technique.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5390},"Title":"Do not hard-code encryption key","Category":"Security","Description":"For a symmetric algorithm to be successful, the secret key must be known only to the sender and the receiver. When a key is hard-coded, it is easily discovered. Even with compiled binaries, it is easy for malicious users to extract it. Once the private key is compromised, the cipher text can be decrypted directly and is not protected anymore.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5391},"Title":"Use antiforgery tokens in ASP.NET Core MVC controllers","Category":"Security","Description":"Handling a POST, PUT, PATCH, or DELETE request without validating an antiforgery token may be vulnerable to cross-site request forgery attacks. A cross-site request forgery attack can send malicious requests from an authenticated user to your ASP.NET Core MVC controller.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5392},"Title":"Use DefaultDllImportSearchPaths attribute for P/Invokes","Category":"Security","Description":"By default, P/Invoke functions using System.Runtime.InteropServices.DllImportAttribute probe a number of directories, including the current working directory for the library to load. This can be a security issue for certain applications, leading to DLL hijacking.\r\nFor example, if a malicious DLL with the same name as the imported one is placed under the current working directory, which will be searched firstly by default, then the malicious DLL could be loaded.\r\nFor more information, see Load Library Safely.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5393},"Title":"Do not use unsafe DllImportSearchPath value","Category":"Security","Description":"There could be a malicious DLL in the default DLL search directories and assembly directories. Or, depending on where your application is run from, there could be a malicious DLL in the application\u0027s directory.\r\nFor more information, see Load Library Safely.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5394},"Title":"Do not use insecure randomness","Category":"Security","Description":"Using a cryptographically weak pseudo-random number generator may allow an attacker to predict what security-sensitive value will be generated.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5395},"Title":"Miss HttpVerb attribute for action methods","Category":"Security","Description":"All the action methods that create, edit, delete, or otherwise modify data needs to be protected with the antiforgery attribute from cross-site request forgery attacks. Performing a GET operation should be a safe operation that has no side effects and doesn\u0027t modify your persisted data.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5396},"Title":"Set HttpOnly to true for HttpCookie","Category":"Security","Description":"As a defense in depth measure, ensure security sensitive HTTP cookies are marked as HttpOnly. This indicates web browsers should disallow scripts from accessing the cookies. Injected malicious scripts are a common way of stealing cookies.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5397},"Title":"Do not use deprecated SslProtocols values","Category":"Security","Description":"Transport Layer Security (TLS) secures communication between computers, most commonly with Hypertext Transfer Protocol Secure (HTTPS). Older protocol versions of TLS are less secure than TLS 1.2 and TLS 1.3 and are more likely to have new vulnerabilities. Avoid older protocol versions to minimize risk. For guidance on identifying and removing deprecated protocol versions, see Solving the TLS 1.0 Problem, 2nd Edition.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5398},"Title":"Avoid hardcoded SslProtocols values","Category":"Security","Description":"Transport Layer Security (TLS) secures communication between computers, most commonly with Hypertext Transfer Protocol Secure (HTTPS). Protocol versions TLS 1.0 and TLS 1.1 are deprecated, while TLS 1.2 and TLS 1.3 are current. In the future, TLS 1.2 and TLS 1.3 may be deprecated. To ensure that your application remains secure, avoid hardcoding a protocol version. For more information, see Transport Layer Security (TLS) best practices with .NET Framework.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5399},"Title":"Enable HttpClient certificate revocation list check","Category":"Security","Description":"A revoked certificate isn\u0027t trusted anymore. It could be used by attackers passing some malicious data or stealing sensitive data in HTTPS communication.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5400},"Title":"Ensure HttpClient certificate revocation list check is not disabled","Category":"Security","Description":"A revoked certificate isn\u0027t trusted anymore. It could be used by attackers passing some malicious data or stealing sensitive data in HTTPS communication.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5401},"Title":"Do not use CreateEncryptor with non-default IV","Category":"Security","Description":"Symmetric encryption should always use a non-repeatable initialization vector to prevent dictionary attacks.\r\nThis rule is similar to CA5402, but analysis determines that the initialization vector is definitely the default.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5402},"Title":"Use CreateEncryptor with the default IV","Category":"Security","Description":"Symmetric encryption should always use a non-repeatable initialization vector to prevent dictionary attacks.\r\nThis rule is similar to CA5401, but analysis can\u0027t determine that the initialization vector is definitely the default.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5403},"Title":"Do not hard-code certificate","Category":"Security","Description":"A hard-coded certificate\u0027s private key is easily discovered. Even with compiled binaries, it is easy for malicious users to extract a hard-coded certificate\u0027s private key. Once the private key is compromised, an attacker can impersonate that certificate, and any resources or operations protected by that certificate will be available to the attacker.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5404},"Title":"Do not disable token validation checks","Category":"Security","Description":"Token validation checks ensure that while validating tokens, all aspects are analyzed and verified. Turning off validation can lead to security holes by allowing untrusted tokens to make it through validation.\r\nMore details about best practices for token validation can be found on the library\u0027s wiki.","Options":[]},{"RuleId":{"RuleType":"CA","Id":5405},"Title":"Do not always skip token validation in delegates","Category":"Security","Description":"By setting critical TokenValidationParameter validation delegates to always return true, important authentication safeguards are disabled. Disabling safeguards can lead to incorrect validation of tokens from any issuer or expired tokens.\r\nFor more information about best practices for token validation, see the library\u0027s wiki.","Options":[]}],"StyleRuleGroups":[{"Rules":[{"RuleId":{"RuleType":"IDE","Id":1},"Title":"Simplify name","Category":"Style"}],"Options":[],"Overview":"This rule concerns the use of simplified type names in declarations and executable code, when possible. You can remove unnecessary name qualification to simplify code and improve readability.","Example":"using System.IO;\r\nclass C\r\n{\r\n // IDE0001: \u0027System.IO.FileInfo\u0027 can be simplified to \u0027FileInfo\u0027\r\n System.IO.FileInfo file;\r\n\r\n // Fixed code\r\n FileInfo file;\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":2},"Title":"Simplify member access","Category":"Style"}],"Options":[],"Overview":"This rule concerns use of simplified type member access in declarations and executable code, when possible. Unnecessary qualification can be removed to simplify code and improve readability.","Example":"class C\r\n{\r\n static void M1() { }\r\n\r\n static void M2()\r\n {\r\n // IDE0002: \u0027C.M1\u0027 can be simplified to \u0027M1\u0027\r\n C.M1();\r\n\r\n // Fixed code\r\n M1();\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":3},"Title":"Remove this or Me qualification","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":9},"Title":"Add this or Me qualification","Category":"Style"}],"Options":[{"Name":"dotnet_style_qualification_for_field","Values":[{"Value":"true","Description":"Prefer fields to be prefaced with this. in C# or Me. in Visual Basic"},{"Value":"false","Description":"Prefer fields not to be prefaced with this. or Me."}],"DefaultValue":"false","CsharpCodeSample":"// dotnet_style_qualification_for_field = true\r\nthis.capacity = 0;\r\n\r\n// dotnet_style_qualification_for_field = false\r\ncapacity = 0;"},{"Name":"dotnet_style_qualification_for_property","Values":[{"Value":"true","Description":"Prefer properties to be prefaced with this. in C# or Me. in Visual Basic."},{"Value":"false","Description":"Prefer properties not to be prefaced with this. or Me.."}],"DefaultValue":"false","CsharpCodeSample":"// dotnet_style_qualification_for_property = true\r\nthis.ID = 0;\r\n\r\n// dotnet_style_qualification_for_property = false\r\nID = 0;"},{"Name":"dotnet_style_qualification_for_method","Values":[{"Value":"true","Description":"Prefer methods to be prefaced with this. in C# or Me. in Visual Basic."},{"Value":"false","Description":"Prefer methods not to be prefaced with this. or Me.."}],"DefaultValue":"false","CsharpCodeSample":"// dotnet_style_qualification_for_method = true\r\nthis.Display();\r\n\r\n// dotnet_style_qualification_for_method = false\r\nDisplay();"},{"Name":"dotnet_style_qualification_for_event","Values":[{"Value":"true","Description":"Prefer events to be prefaced with this. in C# or Me. in Visual Basic."},{"Value":"false","Description":"Prefer events not to be prefaced with this. or Me.."}],"DefaultValue":"false","CsharpCodeSample":"// dotnet_style_qualification_for_event = true\r\nthis.Elapsed \u002B= Handler;\r\n\r\n// dotnet_style_qualification_for_event = false\r\nElapsed \u002B= Handler;"}],"Overview":"These two rules define whether or not you prefer the use of this (C#) and Me. (Visual Basic) qualifiers. To enforce that the qualifiers aren\u0027t present, set the severity of IDE0003 to warning or error. To enforce that the qualifiers are present, set the severity of IDE0009 to warning or error.\r\nFor example, if you prefer qualifiers for fields and properties but not for methods or events, then you can enable IDE0009 and set the options dotnet_style_qualification_for_field and dotnet_style_qualification_for_property to true. However, this configuration would not flag methods and events that do have this and Me qualifiers. To also enforce that methods and events don\u0027t have qualifiers, enable IDE0003.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":4},"Title":"Remove unnecessary cast","Category":"Style"}],"Options":[],"Overview":"This rule flags unnecessary type casts. A cast expression is unnecessary if the code semantics would be identical with or without it.","Example":"// Code with violations\r\nint v = (int)0;\r\n\r\n// Fixed code\r\nint v = 0;"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":5},"Title":"Remove unnecessary import","Category":"Style"}],"Options":[],"Overview":"This rule flags the following unnecessary constructs. If unnecessary, these constructs can be removed without changing the semantics of the code:\r\nusing directives (C#).\r\n Import statements (Visual Basic).\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nTo enable this rule on build, you need to enable XML documentation comments for the project. For more information, see dotnet/roslyn issue 41640.","Example":"// Code with violations\r\nusing System;\r\nusing System.IO; // IDE0005: Using directive is unnecessary\r\nclass C\r\n{\r\n public static void M()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n}\r\n\r\n// Fixed code\r\nusing System;\r\nclass C\r\n{\r\n public static void M()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":7},"Title":"Use var instead of explicit type","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":8},"Title":"Use explicit type instead of var","Category":"Style"}],"Options":[{"Name":"csharp_style_var_for_built_in_types","Values":[{"Value":"true","Description":"Prefer var is used to declare variables with built-in system types such as int"},{"Value":"false","Description":"Prefer explicit type over var to declare variables with built-in system types such as int"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_var_for_built_in_types = true\r\nvar x = 5;\r\n\r\n// csharp_style_var_for_built_in_types = false\r\nint x = 5;"},{"Name":"csharp_style_var_when_type_is_apparent","Values":[{"Value":"true","Description":"Prefer var when the type is already mentioned on the right-hand side of a declaration expression"},{"Value":"false","Description":"Prefer explicit type when the type is already mentioned on the right-hand side of a declaration expression"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_var_when_type_is_apparent = true\r\nvar obj = new Customer();\r\n\r\n// csharp_style_var_when_type_is_apparent = false\r\nCustomer obj = new Customer();"},{"Name":"csharp_style_var_elsewhere","Values":[{"Value":"true","Description":"Prefer var over explicit type in all cases, unless overridden by another code style rule"},{"Value":"false","Description":"Prefer explicit type over var in all cases, unless overridden by another code style rule"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_var_elsewhere = true\r\nvar f = this.Init();\r\n\r\n// csharp_style_var_elsewhere = false\r\nbool f = this.Init();"}],"Overview":"These two style rules define whether the var keyword or an explicit type should be used in a variable declaration. To enforce that var is used, set the severity of IDE0007 to warning or error. To enforce that the explicit type is used, set the severity of IDE0008 to warning or error.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":10},"Title":"Add missing cases to switch statement","Category":"Style"}],"Options":[],"Overview":"This rule concerns specifying all the missing switch cases for a switch statement. A switch statement is considered incomplete in the following scenarios:\r\nAn enum switch statement that\u0027s missing cases for one or more enum members.\r\n A switch statement with a missing default case.","Example":"enum E\r\n{\r\n A,\r\n B\r\n}\r\n\r\nclass C\r\n{\r\n // Code with violations\r\n int M(E e)\r\n {\r\n // IDE0010: Add missing cases\r\n switch (e)\r\n {\r\n case E.A:\r\n return 0;\r\n }\r\n\r\n return -1;\r\n }\r\n\r\n // Fixed code\r\n int M(E e)\r\n {\r\n switch (e)\r\n {\r\n case E.A:\r\n return 0;\r\n case E.B:\r\n return 1;\r\n default:\r\n return -1;\r\n }\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":11},"Title":"Add braces","Category":"Style"}],"Options":[{"Name":"csharp_prefer_braces","Values":[{"Value":"true","Description":"Prefer curly braces even for one line of code"},{"Value":"false","Description":"Prefer no curly braces if allowed"},{"Value":"when_multiline","Description":"Prefer curly braces on multiple lines"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_prefer_braces = true\r\nif (test) { this.Display(); }\r\n\r\n// csharp_prefer_braces = false\r\nif (test) this.Display();\r\n\r\n// csharp_prefer_braces = when_multiline\r\nif (test) this.Display();\r\nelse { this.Display(); Console.WriteLine(\u0022Multiline\u0022); }"}],"Overview":"This style rule concerns the use of curly braces { } to surround code blocks.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":16},"Title":"Use throw expression","Category":"Style"}],"Options":[{"Name":"csharp_style_throw_expression","Values":[{"Value":"true","Description":"Prefer to use throw expressions instead of throw statements"},{"Value":"false","Description":"Prefer to use throw statements instead of throw expressions"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_throw_expression = true\r\nthis.s = s ?? throw new ArgumentNullException(nameof(s));\r\n\r\n// csharp_style_throw_expression = false\r\nif (s == null) { throw new ArgumentNullException(nameof(s)); }\r\nthis.s = s;"}],"Overview":"This style rule concerns the use of throw expressions instead of throw statements. Set the severity of rule IDE0016 to define how the rule should be enforced, for example, as a warning or an error.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":17},"Title":"Use object initializers","Category":"Style"}],"Options":[{"Name":"dotnet_style_object_initializer","Values":[{"Value":"true","Description":"Prefer objects to be initialized using object initializers when possible"},{"Value":"false","Description":"Prefer objects to not be initialized using object initializers"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_object_initializer = true\r\nvar c = new Customer() { Age = 21 };\r\n\r\n// dotnet_style_object_initializer = false\r\nvar c = new Customer();\r\nc.Age = 21;"}],"Overview":"This style rule concerns the use of object initializers for object initialization.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":18},"Title":"Inline variable declaration","Category":"Style"}],"Options":[{"Name":"csharp_style_inlined_variable_declaration","Values":[{"Value":"true","Description":"Prefer out variables to be declared inline in the argument list of a method call when possible"},{"Value":"false","Description":"Prefer out variables to be declared before the method call"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_inlined_variable_declaration = true\r\nif (int.TryParse(value, out int i)) {...}\r\n\r\n// csharp_style_inlined_variable_declaration = false\r\nint i;\r\nif (int.TryParse(value, out i)) {...}"}],"Overview":"This style rule concerns whether out variables are declared inline or not. Starting in C# 7, you can declare an out variable in the argument list of a method call, rather than in a separate variable declaration.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":19},"Title":"Use pattern matching to avoid as followed by a null check","Category":"Style"}],"Options":[{"Name":"csharp_style_pattern_matching_over_as_with_null_check","Values":[{"Value":"true","Description":"Prefer pattern matching to determine if something is of a particular type"},{"Value":"false","Description":"Prefer as expressions with null checks to determine if something is of a particular type"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_pattern_matching_over_as_with_null_check = true\r\nif (o is string s) {...}\r\n\r\n// csharp_style_pattern_matching_over_as_with_null_check = false\r\nvar s = o as string;\r\nif (s != null) {...}"}],"Overview":"This style rule concerns the use of C# pattern matching over an as expression followed by a null check. This rule is similar to IDE0260, which flags the use of an as expression followed by a member read through the null-conditional operator.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":20},"Title":"Use pattern matching to avoid is check followed by a cast (with variable)","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":38},"Title":"Use pattern matching to avoid is check followed by a cast (without variable)","Category":"Style"}],"Options":[{"Name":"csharp_style_pattern_matching_over_is_with_cast_check","Values":[{"Value":"true","Description":"Prefer pattern matching instead of is expressions with type casts."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_pattern_matching_over_is_with_cast_check = true\r\nif (o is int i) {...}\r\n\r\n// csharp_style_pattern_matching_over_is_with_cast_check = false\r\nif (o is int) {var i = (int)o; ... }"}],"Overview":"This style rule concerns the use of C# pattern matching, for example, o is int i, over an is check followed by a cast, for example, if (o is int) { ... (int)o ... }. Enable either IDE0020 or IDE0038 based on whether or not the cast expression should be saved into a separate local variable:\r\nIDE0020: Cast expression is saved into a local variable. For example, if (o is int) { var i = (int)o; } saves the result of (int)o in a local variable.\r\n IDE0038: Cast expression is not saved into a local variable. For example, if (o is int) { if ((int)o == 1) { ... } } does not save the result of (int)o into a local variable.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":21},"Title":"Use expression body for constructors","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_constructors","Values":[{"Value":"true","Description":"Prefer expression bodies for constructors"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for constructors when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for constructors"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_expression_bodied_constructors = true\r\npublic Customer(int age) =\u003E Age = age;\r\n\r\n// csharp_style_expression_bodied_constructors = false\r\npublic Customer(int age) { Age = age; }"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for constructors.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":22},"Title":"Use expression body for methods","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_methods","Values":[{"Value":"true","Description":"Prefer expression bodies for methods"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for methods when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for methods"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_expression_bodied_methods = true\r\npublic int GetAge() =\u003E this.Age;\r\n\r\n// csharp_style_expression_bodied_methods = false\r\npublic int GetAge() { return this.Age; }"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for methods.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":23},"Title":"Use expression body for conversion operators","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":24},"Title":"Use expression body for operators","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_operators","Values":[{"Value":"true","Description":"Prefer expression bodies for operators"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for operators when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for operators"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_expression_bodied_operators = true\r\npublic static ComplexNumber operator \u002B (ComplexNumber c1, ComplexNumber c2)\r\n =\u003E new ComplexNumber(c1.Real \u002B c2.Real, c1.Imaginary \u002B c2.Imaginary);\r\n\r\n// csharp_style_expression_bodied_operators = false\r\npublic static ComplexNumber operator \u002B (ComplexNumber c1, ComplexNumber c2)\r\n{ return new ComplexNumber(c1.Real \u002B c2.Real, c1.Imaginary \u002B c2.Imaginary); }"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for operators.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":25},"Title":"Use expression body for properties","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_properties","Values":[{"Value":"true","Description":"Prefer expression bodies for properties"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for properties when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for properties"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_expression_bodied_properties = true\r\npublic int Age =\u003E _age;\r\n\r\n// csharp_style_expression_bodied_properties = false\r\npublic int Age { get { return _age; }}"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for properties.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":26},"Title":"Use expression body for indexers","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_indexers","Values":[{"Value":"true","Description":"Prefer expression bodies for indexers"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for indexers when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for indexers"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_expression_bodied_indexers = true\r\npublic T this[int i] =\u003E _values[i];\r\n\r\n// csharp_style_expression_bodied_indexers = false\r\npublic T this[int i] { get { return _values[i]; } }"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for indexers.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":27},"Title":"Use expression body for accessors","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_accessors","Values":[{"Value":"true","Description":"Prefer expression bodies for accessors"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for accessors when they will be a single line"},{"Value":"false","Description":"Prefer block bodies for accessors"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_expression_bodied_accessors = true\r\npublic int Age { get =\u003E _age; set =\u003E _age = value; }\r\n\r\n// csharp_style_expression_bodied_accessors = false\r\npublic int Age { get { return _age; } set { _age = value; } }"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for accessors.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":28},"Title":"Use collection initializers","Category":"Style"}],"Options":[{"Name":"dotnet_style_collection_initializer","Values":[{"Value":"true","Description":"Prefer to use collection initializers."},{"Value":"false","Description":"Don\u0027t prefer collection initializers."}],"DefaultValue":"true","CsharpCodeSample":null},{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true","Description":"Prefer to use collection expressions."},{"Value":"false","Description":"Don\u0027t prefer collection expressions."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule concerns the use of collection initializers and, if you\u0027re using C# 12 or later, collection expressions for collection initialization.\r\nIn .NET 8 (C# 12) and later versions, if you have the dotnet_style_prefer_collection_expression option set to true, the code fixer in Visual Studio converts your collection initialization code to use a collection expression (List\u003Cint\u003E list = [1, 2, 3];). In Visual Basic and in .NET 7 (C# 11) and earlier versions, the code fixer converts your code to use a collection initializer (List\u003Cint\u003E list = new List\u003Cint\u003E { 1, 2, 3 };).\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nIf you use the code fixer in Visual Studio, the change it offers might have different semantics in some cases. For example, int[] x = new int[] { } is replaced with int[] x = [];, which has slightly different semantics???the compiler uses a singleton for x instead of creating a new instance.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":29},"Title":"Null check can be simplified (ternary conditional check)","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":30},"Title":"Null check can be simplified (nullable ternary conditional check)","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":270},"Title":"Null check can be simplified (if null check)","Category":"Style"}],"Options":[{"Name":"dotnet_style_coalesce_expression","Values":[{"Value":"true","Description":"Prefer null-coalescing expressions."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"Rules IDE0029 and IDE0030 concern the use of null-coalescing expressions, for example, x ?? y, versus ternary conditional expressions with null checks, for example, x != null ? x : y. The rules differ with respect to the nullability of the expressions:\r\nIDE0029: Used when non-nullable expressions are involved. For example, this rule could recommend x ?? y instead of x != null ? x : y when x and y are non-nullable reference types.\r\n IDE0030: Used when nullable expressions are involved. For example, this rule could recommend x ?? y instead of x != null ? x : y when x and y are nullable value types or nullable reference types.\r\nRule IDE0270 flags the use of a null check (== null or is null) instead of the null-coalescing operator (??).","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":31},"Title":"Use null propagation","Category":"Style"}],"Options":[{"Name":"dotnet_style_null_propagation","Values":[{"Value":"true","Description":"Prefer to use null-conditional operator when possible"},{"Value":"false","Description":"Prefer to use ternary null checking where possible"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_null_propagation = true\r\nvar v = o?.ToString();\r\n\r\n// dotnet_style_null_propagation = false\r\nvar v = o == null ? null : o.ToString(); // or\r\nvar v = o != null ? o.ToString() : null;"}],"Overview":"This style rule concerns the use of the null-conditional operator versus a ternary conditional expression with null check.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":32},"Title":"Use auto-implemented property","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_auto_properties","Values":[{"Value":"true","Description":"Prefer auto-implemented properties"},{"Value":"false","Description":"Prefer properties with private backing fields"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_auto_properties = true\r\npublic int Age { get; }\r\n\r\n// dotnet_style_prefer_auto_properties = false\r\nprivate int age;\r\n\r\npublic int Age\r\n{\r\n get\r\n {\r\n return age;\r\n }\r\n}"}],"Overview":"This style rule concerns the use of auto-implemented properties versus properties with private backing fields.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":33},"Title":"Use explicitly provided tuple name","Category":"Style"}],"Options":[{"Name":"dotnet_style_explicit_tuple_names","Values":[{"Value":"true","Description":"Prefer tuple names to ItemX properties"},{"Value":"false","Description":"Prefer ItemX properties to tuple names"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_explicit_tuple_names = true\r\n(string name, int age) customer = GetCustomer();\r\nvar name = customer.name;\r\n\r\n// dotnet_style_explicit_tuple_names = false\r\n(string name, int age) customer = GetCustomer();\r\nvar name = customer.Item1;"}],"Overview":"This style rule concerns the use of explicit tuple names versus implicit \u0027ItemX\u0027 properties when accessing tuple fields.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":34},"Title":"Simplify default expression","Category":"Style"}],"Options":[{"Name":"csharp_prefer_simple_default_expression","Values":[{"Value":"true","Description":"Prefer default over default(T)"},{"Value":"false","Description":"Prefer default(T) over default"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_prefer_simple_default_expression = true\r\nvoid DoWork(CancellationToken cancellationToken = default) { ... }\r\n\r\n// csharp_prefer_simple_default_expression = false\r\nvoid DoWork(CancellationToken cancellationToken = default(CancellationToken)) { ... }"}],"Overview":"This style rule concerns using the default literal for default value expressions when the compiler can infer the type of the expression.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":35},"Title":"Remove unreachable code","Category":"Style"}],"Options":[],"Overview":"This rule flags executable code within methods and properties that can never be reached, and hence can be removed.","Example":"// Code with violations\r\nvoid M()\r\n{\r\n throw new System.Exception();\r\n\r\n // IDE0035: Remove unreachable code\r\n int v = 0;\r\n}\r\n\r\n// Fixed code\r\nvoid M()\r\n{\r\n throw new System.Exception();\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":36},"Title":"Order modifiers","Category":"Style"}],"Options":[{"Name":"csharp_preferred_modifier_order","Values":[{"Value":"One or more C# modifiers, such as public, private, and protected","Description":""}],"DefaultValue":"public, private, protected, internal, file, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, required, volatile, async","CsharpCodeSample":"// csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async\r\nclass MyClass\r\n{\r\n private static readonly int _daysInYear = 365;\r\n}"}],"Overview":"This rule lets you enforce a desired modifier sort order.\r\nWhen this rule is enabled and the associated options are set to a list of modifiers, prefer the specified ordering.\r\n When this rule is not enabled, no specific modifier order is preferred.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":37},"Title":"Use inferred member name","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_inferred_tuple_names","Values":[{"Value":"true","Description":"Prefer inferred tuple element names"},{"Value":"false","Description":"Prefer explicit tuple element names"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_inferred_tuple_names = true\r\nvar tuple = (age, name);\r\n\r\n// dotnet_style_prefer_inferred_tuple_names = false\r\nvar tuple = (age: age, name: name);"},{"Name":"dotnet_style_prefer_inferred_anonymous_type_member_names","Values":[{"Value":"true","Description":"Prefer inferred anonymous type member names"},{"Value":"false","Description":"Prefer explicit anonymous type member names"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_inferred_anonymous_type_member_names = true\r\nvar anon = new { age, name };\r\n\r\n// dotnet_style_prefer_inferred_anonymous_type_member_names = false\r\nvar anon = new { age = age, name = name };"}],"Overview":"This rule enforces whether inferred tuple element names and inferred anonymous type member names are preferred when the tuple or anonymous type is declared.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":39},"Title":"Use local function instead of lambda","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_local_over_anonymous_function","Values":[{"Value":"true","Description":"Prefer local functions over anonymous functions"},{"Value":"false","Description":"Prefer anonymous functions over local functions"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_prefer_local_over_anonymous_function = true\r\nint fibonacci(int n)\r\n{\r\n return n \u003C= 1 ? 1 : fibonacci(n-1) \u002B fibonacci(n-2);\r\n}\r\n\r\n// csharp_style_prefer_local_over_anonymous_function = false\r\nFunc\u003Cint, int\u003E fibonacci = (int n) =\u003E\r\n{\r\n return n \u003C= 1 ? 1 : fibonacci(n - 1) \u002B fibonacci(n - 2);\r\n};"}],"Overview":"This style rule concerns the use of local functions versus lambda expressions (anonymous functions).","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":40},"Title":"Add accessibility modifiers","Category":"Style"}],"Options":[{"Name":"dotnet_style_require_accessibility_modifiers","Values":[{"Value":"always","Description":"Prefer accessibility modifiers to be specified."},{"Value":"for_non_interface_members","Description":"Prefer accessibility modifiers except for public interface members."},{"Value":"never","Description":"Do not prefer accessibility modifiers to be specified."},{"Value":"omit_if_default","Description":"Prefer accessibility modifiers except if they are the default modifier."}],"DefaultValue":"for_non_interface_members","CsharpCodeSample":"// dotnet_style_require_accessibility_modifiers = always\r\n// dotnet_style_require_accessibility_modifiers = for_non_interface_members\r\nclass MyClass\r\n{\r\n private const string thisFieldIsConst = \u0022constant\u0022;\r\n}\r\n\r\n// dotnet_style_require_accessibility_modifiers = never\r\nclass MyClass\r\n{\r\n const string thisFieldIsConst = \u0022constant\u0022;\r\n}"}],"Overview":"This style rule concerns requiring accessibility modifiers in declarations.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":41},"Title":"Use \u0027is null\u0027 check","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_is_null_check_over_reference_equality_method","Values":[{"Value":"true","Description":"Prefer is null check"},{"Value":"false","Description":"Prefer reference equality method"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_is_null_check_over_reference_equality_method = true\r\nif (value is null)\r\n return;\r\n\r\n// dotnet_style_prefer_is_null_check_over_reference_equality_method = false\r\nif (object.ReferenceEquals(value, null))\r\n return;\r\n\r\n// dotnet_style_prefer_is_null_check_over_reference_equality_method = false\r\nif ((object)o == null)\r\n return;"}],"Overview":"This style rule concerns the use of a null check with pattern matching versus the use of the equality operator (==) or calling System.Object.ReferenceEquals(System.Object,System.Object).","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":42},"Title":"Deconstruct variable declaration","Category":"Style"}],"Options":[{"Name":"csharp_style_deconstructed_variable_declaration","Values":[{"Value":"true","Description":"Prefer deconstructed variable declaration"},{"Value":"false","Description":"Do not prefer deconstruction in variable declarations"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_deconstructed_variable_declaration = true\r\nvar (name, age) = GetPersonTuple();\r\nConsole.WriteLine($\u0022{name} {age}\u0022);\r\n\r\n(int x, int y) = GetPointTuple();\r\nConsole.WriteLine($\u0022{x} {y}\u0022);\r\n\r\n// csharp_style_deconstructed_variable_declaration = false\r\nvar person = GetPersonTuple();\r\nConsole.WriteLine($\u0022{person.name} {person.age}\u0022);\r\n\r\n(int x, int y) point = GetPointTuple();\r\nConsole.WriteLine($\u0022{point.x} {point.y}\u0022);"}],"Overview":"This style rule concerns the use of deconstruction in variable declarations, when possible.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":44},"Title":"Add readonly modifier","Category":"Style"}],"Options":[{"Name":"dotnet_style_readonly_field","Values":[{"Value":"true","Description":"Prefer that private fields be marked readonly if they\u0027re only ever assigned inline or in a constructor"},{"Value":"false","Description":"Specify no preference over whether private fields are marked readonly"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_readonly_field = true\r\nclass MyClass\r\n{\r\n private readonly int _daysInYear = 365;\r\n}"}],"Overview":"This style rule concerns specifying the readonly (C#) or ReadOnly (Visual Basic) modifier for private fields that are initialized (either inline or inside of a constructor) but never reassigned.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":45},"Title":"Use conditional expression for assignment","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_conditional_expression_over_assignment","Values":[{"Value":"true","Description":"Prefer assignments with a ternary conditional"},{"Value":"false","Description":"Prefer assignments with an if-else statement"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_conditional_expression_over_assignment = true\r\nstring s = expr ? \u0022hello\u0022 : \u0022world\u0022;\r\n\r\n// dotnet_style_prefer_conditional_expression_over_assignment = false\r\nstring s;\r\nif (expr)\r\n{\r\n s = \u0022hello\u0022;\r\n}\r\nelse\r\n{\r\n s = \u0022world\u0022;\r\n}"}],"Overview":"This style rule concerns the use of a ternary conditional expression versus an if-else statement for assignments that require conditional logic.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":46},"Title":"Use conditional expression for return","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_conditional_expression_over_return","Values":[{"Value":"true","Description":"Prefer return statements to use a ternary conditional"},{"Value":"false","Description":"Prefer return statements to use an if-else statement"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_conditional_expression_over_return = true\r\nreturn expr ? \u0022hello\u0022 : \u0022world\u0022\r\n\r\n// dotnet_style_prefer_conditional_expression_over_return = false\r\nif (expr)\r\n{\r\n return \u0022hello\u0022;\r\n}\r\nelse\r\n{\r\n return \u0022world\u0022;\r\n}"}],"Overview":"This style rule concerns the use of a ternary conditional expression versus an if-else statement for return statements that require conditional logic.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":47},"Title":"Remove unnecessary parentheses","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":48},"Title":"Add parentheses for clarity","Category":"Style"}],"Options":[{"Name":"dotnet_style_parentheses_in_arithmetic_binary_operators","Values":[{"Value":"always_for_clarity","Description":"Prefer parentheses to clarify arithmetic operator precedence"},{"Value":"never_if_unnecessary","Description":"Prefer no parentheses when arithmetic operator precedence is obvious"}],"DefaultValue":"always_for_clarity","CsharpCodeSample":"// dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity\r\nvar v = a \u002B (b * c);\r\n\r\n// dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary\r\nvar v = a \u002B b * c;"},{"Name":"dotnet_style_parentheses_in_relational_binary_operators","Values":[{"Value":"always_for_clarity","Description":"Prefer parentheses to clarify relational operator precedence"},{"Value":"never_if_unnecessary","Description":"Prefer to not have parentheses when relational operator precedence is obvious"}],"DefaultValue":"always_for_clarity","CsharpCodeSample":"// dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity\r\nvar v = (a \u003C b) == (c \u003E d);\r\n\r\n// dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary\r\nvar v = a \u003C b == c \u003E d;"},{"Name":"dotnet_style_parentheses_in_other_binary_operators","Values":[{"Value":"always_for_clarity","Description":"Prefer parentheses to clarify other binary operator precedence"},{"Value":"never_if_unnecessary","Description":"Prefer to not have parentheses when other binary operator precedence is obvious"}],"DefaultValue":"always_for_clarity","CsharpCodeSample":"// dotnet_style_parentheses_in_other_binary_operators = always_for_clarity\r\nvar v = a || (b \u0026\u0026 c);\r\n\r\n// dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary\r\nvar v = a || b \u0026\u0026 c;"},{"Name":"dotnet_style_parentheses_in_other_operators","Values":[{"Value":"always_for_clarity","Description":"Prefer parentheses to clarify other operator precedence"},{"Value":"never_if_unnecessary","Description":"Prefer to not have parentheses when other operator precedence is obvious"}],"DefaultValue":"never_if_unnecessary","CsharpCodeSample":"// dotnet_style_parentheses_in_other_operators = always_for_clarity\r\nvar v = (a.b).Length;\r\n\r\n// dotnet_style_parentheses_in_other_operators = never_if_unnecessary\r\nvar v = a.b.Length;"}],"Overview":"The style rules in this section concern parentheses preferences, including the use of parentheses to clarify precedence for arithmetic, relational, and other binary operators.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":49},"Title":"Use language keywords instead of framework type names for type references","Category":"Style"}],"Options":[{"Name":"dotnet_style_predefined_type_for_locals_parameters_members","Values":[{"Value":"true","Description":"Prefer the language keyword for local variables, method parameters, and class members"},{"Value":"false","Description":"Prefer the type name for local variables, method parameters, and class members"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_predefined_type_for_locals_parameters_members = true\r\nprivate int _member;\r\n\r\n// dotnet_style_predefined_type_for_locals_parameters_members = false\r\nprivate Int32 _member;"},{"Name":"dotnet_style_predefined_type_for_member_access","Values":[{"Value":"true","Description":"Prefer the language keyword for member access expressions"},{"Value":"false","Description":"Prefer the type name for member access expressions"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_predefined_type_for_member_access = true\r\nvar local = int.MaxValue;\r\n\r\n// dotnet_style_predefined_type_for_member_access = false\r\nvar local = Int32.MaxValue;"}],"Overview":"This rule concerns the use of language keywords, where they exist, instead of framework type names.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":50},"Title":"Convert anonymous type to tuple","Category":"Style"}],"Options":[],"Overview":"This rule recommends use of tuples over anonymous types, when the anonymous type has two or more fields.","Example":"// Code with violations\r\nvar t1 = new { a = 1, b = 2 };\r\n\r\n// Fixed code\r\nvar t1 = (a: 1, b: 2);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":51},"Title":"Remove unused private member","Category":"CodeQuality"}],"Options":[],"Overview":"This rule flags unused private methods, fields, properties, and events that have no read or write references.","Example":"// Code with violations\r\nclass C\r\n{\r\n // IDE0051: Remove unused private members\r\n private readonly int _fieldPrivate;\r\n private int PropertyPrivate =\u003E 1;\r\n private int GetNumPrivate() =\u003E 1;\r\n\r\n // No IDE0051\r\n internal readonly int FieldInternal;\r\n private readonly int _fieldPrivateUsed;\r\n public int PropertyPublic =\u003E _fieldPrivateUsed;\r\n private int GetNumPrivateUsed() =\u003E 1;\r\n internal int GetNumInternal() =\u003E GetNumPrivateUsed();\r\n public int GetNumPublic() =\u003E GetNumPrivateUsed();\r\n}\r\n\r\n// Fixed code\r\nclass C\r\n{\r\n // No IDE0051\r\n internal readonly int FieldInternal;\r\n private readonly int _fieldPrivateUsed;\r\n public int PropertyPublic =\u003E _fieldPrivateUsed;\r\n private int GetNumPrivateUsed() =\u003E 1;\r\n internal int GetNumInternal() =\u003E GetNumPrivateUsed();\r\n public int GetNumPublic() =\u003E GetNumPrivateUsed();\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":52},"Title":"Remove unread private member","Category":"CodeQuality"}],"Options":[],"Overview":"This rule flags private fields and properties that have one or more write references but no read references. In this scenario, some parts of the code can be refactored or removed to fix maintainability, performance, or functional issues.","Example":"// Code with violations\r\nclass C\r\n{\r\n // IDE0052: Remove unread private members\r\n private readonly int _field1;\r\n private int _field2;\r\n private int Property { get; set; }\r\n\r\n public C()\r\n {\r\n _field1 = 0;\r\n }\r\n\r\n public void SetMethod()\r\n {\r\n _field2 = 0;\r\n Property = 0;\r\n }\r\n}\r\n\r\n// Fixed code\r\nclass C\r\n{\r\n public C()\r\n {\r\n }\r\n\r\n public void SetMethod()\r\n {\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":53},"Title":"Use expression body for lambdas","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_lambdas","Values":[{"Value":"true","Description":"Prefer expression bodies for lambdas"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for lambdas when they\u0027ll be a single line"},{"Value":"false","Description":"Prefer block bodies for lambdas"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_expression_bodied_lambdas = true\r\nFunc\u003Cint, int\u003E square = x =\u003E x * x;\r\n\r\n// csharp_style_expression_bodied_lambdas = false\r\nFunc\u003Cint, int\u003E square = x =\u003E { return x * x; };"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for lambda expressions.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":54},"Title":"Use compound assignment","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":74},"Title":"Use coalesce compound assignment","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_compound_assignment","Values":[{"Value":"true","Description":"Prefer compound assignment expressions"},{"Value":"false","Description":"Don\u0027t prefer compound assignment expressions"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_compound_assignment = true\r\nx \u002B= 5;\r\n\r\n// dotnet_style_prefer_compound_assignment = false\r\nx = x \u002B 5;"}],"Overview":"These rules concern the use of compound assignment. IDE0074 is reported for coalesce compound assignments and IDE0054 is reported for other compound assignments.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":55},"Title":"Formatting rule","Category":"Style"}],"Options":[{"Name":"dotnet_sort_system_directives_first","Values":[{"Value":"true","Description":"Sort System.* using directives alphabetically, and place them before other using directives."},{"Value":"false","Description":"Do not place System.* using directives before other using directives."}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_sort_system_directives_first = true\r\nusing System.Collections.Generic;\r\nusing System.Threading.Tasks;\r\nusing Octokit;\r\n\r\n// dotnet_sort_system_directives_first = false\r\nusing System.Collections.Generic;\r\nusing Octokit;\r\nusing System.Threading.Tasks;"},{"Name":"dotnet_separate_import_directive_groups","Values":[{"Value":"true","Description":"Place a blank line between using directive groups."},{"Value":"false","Description":"Do not place a blank line between using directive groups."}],"DefaultValue":"false","CsharpCodeSample":"// dotnet_separate_import_directive_groups = true\r\nusing System.Collections.Generic;\r\nusing System.Threading.Tasks;\r\n\r\nusing Octokit;\r\n\r\n// dotnet_separate_import_directive_groups = false\r\nusing System.Collections.Generic;\r\nusing System.Threading.Tasks;\r\nusing Octokit;"},{"Name":"csharp_new_line_before_open_brace","Values":[{"Value":"all","Description":"Require braces to be on a new line for all expressions (\u0022Allman\u0022 style)."},{"Value":"none","Description":"Require braces to be on the same line for all expressions (\u0022K\u0026R\u0022)."},{"Value":"accessors, anonymous_methods, anonymous_types, control_blocks, events, indexers,lambdas, local_functions, methods, object_collection_array_initializers, properties, types","Description":"Require braces to be on a new line for the specified code element (\u0022Allman\u0022 style)."}],"DefaultValue":"all","CsharpCodeSample":"// csharp_new_line_before_open_brace = all\r\nvoid MyMethod()\r\n{\r\n if (...)\r\n {\r\n ...\r\n }\r\n}\r\n\r\n// csharp_new_line_before_open_brace = none\r\nvoid MyMethod() {\r\n if (...) {\r\n ...\r\n }\r\n}"},{"Name":"csharp_new_line_before_else","Values":[{"Value":"true","Description":"Place else statements on a new line."},{"Value":"false","Description":"Place else statements on the same line."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_before_else = true\r\nif (...) {\r\n ...\r\n}\r\nelse {\r\n ...\r\n}\r\n\r\n// csharp_new_line_before_else = false\r\nif (...) {\r\n ...\r\n} else {\r\n ...\r\n}"},{"Name":"csharp_new_line_before_catch","Values":[{"Value":"true","Description":"Place catch statements on a new line."},{"Value":"false","Description":"Place catch statements on the same line."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_before_catch = true\r\ntry {\r\n ...\r\n}\r\ncatch (Exception e) {\r\n ...\r\n}\r\n\r\n// csharp_new_line_before_catch = false\r\ntry {\r\n ...\r\n} catch (Exception e) {\r\n ...\r\n}"},{"Name":"csharp_new_line_before_finally","Values":[{"Value":"true","Description":"Require finally statements to be on a new line after the closing brace."},{"Value":"false","Description":"Require finally statements to be on the same line as the closing brace."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_before_finally = true\r\ntry {\r\n ...\r\n}\r\ncatch (Exception e) {\r\n ...\r\n}\r\nfinally {\r\n ...\r\n}\r\n\r\n// csharp_new_line_before_finally = false\r\ntry {\r\n ...\r\n} catch (Exception e) {\r\n ...\r\n} finally {\r\n ...\r\n}"},{"Name":"csharp_new_line_before_members_in_object_initializers","Values":[{"Value":"true","Description":"Require members of object initializers to be on separate lines"},{"Value":"false","Description":"Require members of object initializers to be on the same line"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_before_members_in_object_initializers = true\r\nvar z = new B()\r\n{\r\n A = 3,\r\n B = 4\r\n}\r\n\r\n// csharp_new_line_before_members_in_object_initializers = false\r\nvar z = new B()\r\n{\r\n A = 3, B = 4\r\n}"},{"Name":"csharp_new_line_before_members_in_anonymous_types","Values":[{"Value":"true","Description":"Require members of anonymous types to be on separate lines"},{"Value":"false","Description":"Require members of anonymous types to be on the same line"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_before_members_in_anonymous_types = true\r\nvar z = new\r\n{\r\n A = 3,\r\n B = 4\r\n}\r\n\r\n// csharp_new_line_before_members_in_anonymous_types = false\r\nvar z = new\r\n{\r\n A = 3, B = 4\r\n}"},{"Name":"csharp_new_line_between_query_expression_clauses","Values":[{"Value":"true","Description":"Require elements of query expression clauses to be on separate lines"},{"Value":"false","Description":"Require elements of query expression clauses to be on the same line"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_new_line_between_query_expression_clauses = true\r\nvar q = from a in e\r\n from b in e\r\n select a * b;\r\n\r\n// csharp_new_line_between_query_expression_clauses = false\r\nvar q = from a in e from b in e\r\n select a * b;"},{"Name":"csharp_indent_case_contents","Values":[{"Value":"true","Description":"Indent switch case contents"},{"Value":"false","Description":"Do not indent switch case contents"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_indent_case_contents = true\r\nswitch(c) {\r\n case Color.Red:\r\n Console.WriteLine(\u0022The color is red\u0022);\r\n break;\r\n case Color.Blue:\r\n Console.WriteLine(\u0022The color is blue\u0022);\r\n break;\r\n default:\r\n Console.WriteLine(\u0022The color is unknown.\u0022);\r\n break;\r\n}\r\n\r\n// csharp_indent_case_contents = false\r\nswitch(c) {\r\n case Color.Red:\r\n Console.WriteLine(\u0022The color is red\u0022);\r\n break;\r\n case Color.Blue:\r\n Console.WriteLine(\u0022The color is blue\u0022);\r\n break;\r\n default:\r\n Console.WriteLine(\u0022The color is unknown.\u0022);\r\n break;\r\n}"},{"Name":"csharp_indent_switch_labels","Values":[{"Value":"true","Description":"Indent switch labels"},{"Value":"false","Description":"Do not indent switch labels"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_indent_switch_labels = true\r\nswitch(c) {\r\n case Color.Red:\r\n Console.WriteLine(\u0022The color is red\u0022);\r\n break;\r\n case Color.Blue:\r\n Console.WriteLine(\u0022The color is blue\u0022);\r\n break;\r\n default:\r\n Console.WriteLine(\u0022The color is unknown.\u0022);\r\n break;\r\n}\r\n\r\n// csharp_indent_switch_labels = false\r\nswitch(c) {\r\ncase Color.Red:\r\n Console.WriteLine(\u0022The color is red\u0022);\r\n break;\r\ncase Color.Blue:\r\n Console.WriteLine(\u0022The color is blue\u0022);\r\n break;\r\ndefault:\r\n Console.WriteLine(\u0022The color is unknown.\u0022);\r\n break;\r\n}"},{"Name":"csharp_indent_labels","Values":[{"Value":"flush_left","Description":"Labels are placed at the leftmost column"},{"Value":"one_less_than_current","Description":"Labels are placed at one less indent to the current context"},{"Value":"no_change","Description":"Labels are placed at the same indent as the current context"}],"DefaultValue":"one_less_than_current","CsharpCodeSample":"// csharp_indent_labels= flush_left\r\nclass C\r\n{\r\n private string MyMethod(...)\r\n {\r\n if (...) {\r\n goto error;\r\n }\r\nerror:\r\n throw new Exception(...);\r\n }\r\n}\r\n\r\n// csharp_indent_labels = one_less_than_current\r\nclass C\r\n{\r\n private string MyMethod(...)\r\n {\r\n if (...) {\r\n goto error;\r\n }\r\n error:\r\n throw new Exception(...);\r\n }\r\n}\r\n\r\n// csharp_indent_labels= no_change\r\nclass C\r\n{\r\n private string MyMethod(...)\r\n {\r\n if (...) {\r\n goto error;\r\n }\r\n error:\r\n throw new Exception(...);\r\n }\r\n}"},{"Name":"csharp_indent_block_contents","Values":[{"Value":"true","Description":"Indent block contents."},{"Value":"false","Description":"Don\u0027t indent block contents."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_indent_block_contents = true\r\nstatic void Hello()\r\n{\r\n Console.WriteLine(\u0022Hello\u0022);\r\n}\r\n\r\n// csharp_indent_block_contents = false\r\nstatic void Hello()\r\n{\r\nConsole.WriteLine(\u0022Hello\u0022);\r\n}"},{"Name":"csharp_indent_braces","Values":[{"Value":"true","Description":"Indent curly braces."},{"Value":"false","Description":"Don\u0027t indent curly braces."}],"DefaultValue":"false","CsharpCodeSample":"// csharp_indent_braces = true\r\nstatic void Hello()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n\r\n// csharp_indent_braces = false\r\nstatic void Hello()\r\n{\r\n Console.WriteLine(\u0022Hello\u0022);\r\n}"},{"Name":"csharp_indent_case_contents_when_block","Values":[{"Value":"true","Description":"When it\u0027s a block, indent the statement list and curly braces for a case in a switch statement."},{"Value":"false","Description":"When it\u0027s a block, don\u0027t indent the statement list and curly braces for a case in a switch statement."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_indent_case_contents_when_block = true\r\ncase 0:\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n break;\r\n }\r\n\r\n// csharp_indent_case_contents_when_block = false\r\ncase 0:\r\n{\r\n Console.WriteLine(\u0022Hello\u0022);\r\n break;\r\n}"},{"Name":"csharp_space_after_cast","Values":[{"Value":"true","Description":"Place a space character between a cast and the value"},{"Value":"false","Description":"Remove space between the cast and the value"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_after_cast = true\r\nint y = (int) x;\r\n\r\n// csharp_space_after_cast = false\r\nint y = (int)x;"},{"Name":"csharp_space_after_keywords_in_control_flow_statements","Values":[{"Value":"true","Description":"Place a space character after a keyword in a control flow statement such as a for loop"},{"Value":"false","Description":"Remove space after a keyword in a control flow statement such as a for loop"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_space_after_keywords_in_control_flow_statements = true\r\nfor (int i;i\u003Cx;i\u002B\u002B) { ... }\r\n\r\n// csharp_space_after_keywords_in_control_flow_statements = false\r\nfor(int i;i\u003Cx;i\u002B\u002B) { ... }"},{"Name":"csharp_space_between_parentheses","Values":[{"Value":"control_flow_statements","Description":"Place space between parentheses of control flow statements"},{"Value":"expressions","Description":"Place space between parentheses of expressions"},{"Value":"type_casts","Description":"Place space between parentheses in type casts"},{"Value":"false (or any other value)","Description":"Never add spaces between parentheses"}],"DefaultValue":null,"CsharpCodeSample":"// csharp_space_between_parentheses = control_flow_statements\r\nfor ( int i = 0; i \u003C 10; i\u002B\u002B ) { }\r\n\r\n// csharp_space_between_parentheses = expressions\r\nvar z = ( x * y ) - ( ( y - x ) * 3 );\r\n\r\n// csharp_space_between_parentheses = type_casts\r\nint y = ( int )x;\r\n\r\n// csharp_space_between_parentheses = false\r\nint y = (int)x;"},{"Name":"csharp_space_before_colon_in_inheritance_clause","Values":[{"Value":"true","Description":"Place a space character before the colon for bases or interfaces in a type declaration"},{"Value":"false","Description":"Remove space before the colon for bases or interfaces in a type declaration"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_space_before_colon_in_inheritance_clause = true\r\ninterface I\r\n{\r\n\r\n}\r\n\r\nclass C : I\r\n{\r\n\r\n}\r\n\r\n// csharp_space_before_colon_in_inheritance_clause = false\r\ninterface I\r\n{\r\n\r\n}\r\n\r\nclass C: I\r\n{\r\n\r\n}"},{"Name":"csharp_space_after_colon_in_inheritance_clause","Values":[{"Value":"true","Description":"Place a space character after the colon for bases or interfaces in a type declaration"},{"Value":"false","Description":"Remove space after the colon for bases or interfaces in a type declaration"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_space_after_colon_in_inheritance_clause = true\r\ninterface I\r\n{\r\n\r\n}\r\n\r\nclass C : I\r\n{\r\n\r\n}\r\n\r\n// csharp_space_after_colon_in_inheritance_clause = false\r\ninterface I\r\n{\r\n\r\n}\r\n\r\nclass C :I\r\n{\r\n\r\n}"},{"Name":"csharp_space_around_binary_operators","Values":[{"Value":"before_and_after","Description":"Insert space before and after the binary operator"},{"Value":"none","Description":"Remove spaces before and after the binary operator"},{"Value":"ignore","Description":"Ignore spaces around binary operators"}],"DefaultValue":"before_and_after","CsharpCodeSample":"// csharp_space_around_binary_operators = before_and_after\r\nreturn x * (x - y);\r\n\r\n// csharp_space_around_binary_operators = none\r\nreturn x*(x-y);\r\n\r\n// csharp_space_around_binary_operators = ignore\r\nreturn x * (x-y);"},{"Name":"csharp_space_between_method_declaration_parameter_list_parentheses","Values":[{"Value":"true","Description":"Place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list"},{"Value":"false","Description":"Remove space characters after the opening parenthesis and before the closing parenthesis of a method declaration parameter list"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_declaration_parameter_list_parentheses = true\r\nvoid Bark( int x ) { ... }\r\n\r\n// csharp_space_between_method_declaration_parameter_list_parentheses = false\r\nvoid Bark(int x) { ... }"},{"Name":"csharp_space_between_method_declaration_empty_parameter_list_parentheses","Values":[{"Value":"true","Description":"Insert space within empty parameter list parentheses for a method declaration"},{"Value":"false","Description":"Remove space within empty parameter list parentheses for a method declaration"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_declaration_empty_parameter_list_parentheses = true\r\nvoid Goo( )\r\n{\r\n Goo(1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo();\r\n}\r\n\r\n// csharp_space_between_method_declaration_empty_parameter_list_parentheses = false\r\nvoid Goo()\r\n{\r\n Goo(1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo();\r\n}"},{"Name":"csharp_space_between_method_declaration_name_and_open_parenthesis","Values":[{"Value":"true","Description":"Place a space character between the method name and opening parenthesis in the method declaration"},{"Value":"false","Description":"Remove space characters between the method name and opening parenthesis in the method declaration"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_declaration_name_and_open_parenthesis = true\r\nvoid M () { }\r\n\r\n// csharp_space_between_method_declaration_name_and_open_parenthesis = false\r\nvoid M() { }"},{"Name":"csharp_space_between_method_call_parameter_list_parentheses","Values":[{"Value":"true","Description":"Place a space character after the opening parenthesis and before the closing parenthesis of a method call"},{"Value":"false","Description":"Remove space characters after the opening parenthesis and before the closing parenthesis of a method call"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_call_parameter_list_parentheses = true\r\nMyMethod( argument );\r\n\r\n// csharp_space_between_method_call_parameter_list_parentheses = false\r\nMyMethod(argument);"},{"Name":"csharp_space_between_method_call_empty_parameter_list_parentheses","Values":[{"Value":"true","Description":"Insert space within empty argument list parentheses"},{"Value":"false","Description":"Remove space within empty argument list parentheses"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_call_empty_parameter_list_parentheses = true\r\nvoid Goo()\r\n{\r\n Goo(1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo( );\r\n}\r\n\r\n// csharp_space_between_method_call_empty_parameter_list_parentheses = false\r\nvoid Goo()\r\n{\r\n Goo(1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo();\r\n}"},{"Name":"csharp_space_between_method_call_name_and_opening_parenthesis","Values":[{"Value":"true","Description":"Insert space between method call name and opening parenthesis"},{"Value":"false","Description":"Remove space between method call name and opening parenthesis"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_method_call_name_and_opening_parenthesis = true\r\nvoid Goo()\r\n{\r\n Goo (1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo ();\r\n}\r\n\r\n// csharp_space_between_method_call_name_and_opening_parenthesis = false\r\nvoid Goo()\r\n{\r\n Goo(1);\r\n}\r\n\r\nvoid Goo(int x)\r\n{\r\n Goo();\r\n}"},{"Name":"csharp_space_after_comma","Values":[{"Value":"true","Description":"Insert space after a comma"},{"Value":"false","Description":"Remove space after a comma"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_space_after_comma = true\r\nint[] x = new int[] { 1, 2, 3, 4, 5 };\r\n\r\n// csharp_space_after_comma = false\r\nint[] x = new int[] { 1,2,3,4,5 };"},{"Name":"csharp_space_before_comma","Values":[{"Value":"true","Description":"Insert space before a comma"},{"Value":"false","Description":"Remove space before a comma"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_before_comma = true\r\nint[] x = new int[] { 1 , 2 , 3 , 4 , 5 };\r\n\r\n// csharp_space_before_comma = false\r\nint[] x = new int[] { 1, 2, 3, 4, 5 };"},{"Name":"csharp_space_after_dot","Values":[{"Value":"true","Description":"Insert space after a dot"},{"Value":"false","Description":"Remove space after a dot"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_after_dot = true\r\nthis. Goo();\r\n\r\n// csharp_space_after_dot = false\r\nthis.Goo();"},{"Name":"csharp_space_before_dot","Values":[{"Value":"true","Description":"Insert space before a dot"},{"Value":"false","Description":"Remove space before a dot"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_before_dot = true\r\nthis .Goo();\r\n\r\n// csharp_space_before_dot = false\r\nthis.Goo();"},{"Name":"csharp_space_after_semicolon_in_for_statement","Values":[{"Value":"true","Description":"Insert space after each semicolon in a for statement"},{"Value":"false","Description":"Remove space after each semicolon in a for statement"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_space_after_semicolon_in_for_statement = true\r\nfor (int i = 0; i \u003C x.Length; i\u002B\u002B)\r\n\r\n// csharp_space_after_semicolon_in_for_statement = false\r\nfor (int i = 0;i \u003C x.Length;i\u002B\u002B)"},{"Name":"csharp_space_before_semicolon_in_for_statement","Values":[{"Value":"true","Description":"Insert space before each semicolon in a for statement"},{"Value":"false","Description":"Remove space before each semicolon in a for statement"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_before_semicolon_in_for_statement = true\r\nfor (int i = 0 ; i \u003C x.Length ; i\u002B\u002B)\r\n\r\n// csharp_space_before_semicolon_in_for_statement = false\r\nfor (int i = 0; i \u003C x.Length; i\u002B\u002B)"},{"Name":"csharp_space_around_declaration_statements","Values":[{"Value":"ignore","Description":"Don\u0027t remove extra space characters in declaration statements"},{"Value":"false","Description":"Remove extra space characters in declaration statements"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_around_declaration_statements = ignore\r\nint x = 0 ;\r\n\r\n// csharp_space_around_declaration_statements = false\r\nint x = 0;"},{"Name":"csharp_space_before_open_square_brackets","Values":[{"Value":"true","Description":"Insert space before opening square brackets ["},{"Value":"false","Description":"Remove space before opening square brackets ["}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_before_open_square_brackets = true\r\nint [] numbers = new int [] { 1, 2, 3, 4, 5 };\r\n\r\n// csharp_space_before_open_square_brackets = false\r\nint[] numbers = new int[] { 1, 2, 3, 4, 5 };"},{"Name":"csharp_space_between_empty_square_brackets","Values":[{"Value":"true","Description":"Insert space between empty square brackets [ ]"},{"Value":"false","Description":"Remove space between empty square brackets []"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_empty_square_brackets = true\r\nint[ ] numbers = new int[ ] { 1, 2, 3, 4, 5 };\r\n\r\n// csharp_space_between_empty_square_brackets = false\r\nint[] numbers = new int[] { 1, 2, 3, 4, 5 };"},{"Name":"csharp_space_between_square_brackets","Values":[{"Value":"true","Description":"Insert space characters in non-empty square brackets [ 0 ]"},{"Value":"false","Description":"Remove space characters in non-empty square brackets [0]"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_space_between_square_brackets = true\r\nint index = numbers[ 0 ];\r\n\r\n// csharp_space_between_square_brackets = false\r\nint index = numbers[0];"},{"Name":"csharp_preserve_single_line_statements","Values":[{"Value":"true","Description":"Leave statements and member declarations on the same line"},{"Value":"false","Description":"Leave statements and member declarations on different lines"}],"DefaultValue":"true","CsharpCodeSample":"//csharp_preserve_single_line_statements = true\r\nint i = 0; string name = \u0022John\u0022;\r\n\r\n//csharp_preserve_single_line_statements = false\r\nint i = 0;\r\nstring name = \u0022John\u0022;"},{"Name":"csharp_preserve_single_line_blocks","Values":[{"Value":"true","Description":"Leave code block on single line"},{"Value":"false","Description":"Leave code block on separate lines"}],"DefaultValue":"true","CsharpCodeSample":"//csharp_preserve_single_line_blocks = true\r\npublic int Foo { get; set; }\r\n\r\n//csharp_preserve_single_line_blocks = false\r\npublic int MyProperty\r\n{\r\n get; set;\r\n}"}],"Overview":"","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":56},"Title":"Use index operator","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_index_operator","Values":[{"Value":"true","Description":"Prefer to use the ^ operator when calculating an index from the end of a collection"},{"Value":"false","Description":"Prefer not to use the ^ operator when calculating an index from the end of a collection"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_prefer_index_operator = true\r\nstring[] names = { \u0022Archimedes\u0022, \u0022Pythagoras\u0022, \u0022Euclid\u0022 };\r\nvar index = names[^1];\r\n\r\n// csharp_style_prefer_index_operator = false\r\nstring[] names = { \u0022Archimedes\u0022, \u0022Pythagoras\u0022, \u0022Euclid\u0022 };\r\nvar index = names[names.Length - 1];"}],"Overview":"This style rule concerns the use of the index-from-end operator (^), which is available in C# 8.0 and later.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":57},"Title":"Use range operator","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_range_operator","Values":[{"Value":"true","Description":"Prefer to use the range operator .. when extracting a \u0022slice\u0022 of a collection"},{"Value":"false","Description":"Prefer not to use the range operator .. when extracting a \u0022slice\u0022 of a collection"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_prefer_range_operator = true\r\nstring sentence = \u0022the quick brown fox\u0022;\r\nvar sub = sentence[0..^4];\r\n\r\n// csharp_style_prefer_range_operator = false\r\nstring sentence = \u0022the quick brown fox\u0022;\r\nvar sub = sentence.Substring(0, sentence.Length - 4);"}],"Overview":"This style rule concerns the use of the range operator (..), which is available in C# 8.0 and later.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":58},"Title":"Remove unnecessary expression value","Category":"Style"}],"Options":[{"Name":"csharp_style_unused_value_expression_statement_preference","Values":[{"Value":"discard_variable","Description":"Prefer to assign an unused expression to a discard"},{"Value":"unused_local_variable","Description":"Prefer to assign an unused expression to a local variable that\u0027s never used"}],"DefaultValue":"discard_variable","CsharpCodeSample":"// Original code:\r\nSystem.Convert.ToInt32(\u002235\u0022);\r\n\r\n// After code fix for IDE0058:\r\n\r\n// csharp_style_unused_value_expression_statement_preference = discard_variable\r\n_ = System.Convert.ToInt32(\u002235\u0022);\r\n\r\n// csharp_style_unused_value_expression_statement_preference = unused_local_variable\r\nvar unused = Convert.ToInt32(\u002235\u0022);"}],"Overview":"This rule flags unused expression values. For example:\r\nvoid M()\r\n{\r\n Compute(); // IDE0058: computed value is never used.\r\n}\r\n\r\nint Compute();\r\nYou can take one of the following actions to fix this violation:\r\nIf the expression has no side effects, remove the entire statement. This improves performance by avoiding unnecessary computation.\r\n If the expression has side effects, replace the left side of the assignment with a discard (C# only) or a local variable that\u0027s never used. This improves code clarity by explicitly showing the intent to discard an unused value.\r\n _ = Compute();","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":59},"Title":"Remove unnecessary value assignment","Category":"Style"}],"Options":[{"Name":"csharp_style_unused_value_assignment_preference","Values":[{"Value":"discard_variable","Description":"Prefer to use a discard when assigning a value that\u0027s not used"},{"Value":"unused_local_variable","Description":"Prefer to use a local variable when assigning a value that\u0027s not used"}],"DefaultValue":"discard_variable","CsharpCodeSample":"// csharp_style_unused_value_assignment_preference = discard_variable\r\nint GetCount(Dictionary\u003Cstring, int\u003E wordCount, string searchWord)\r\n{\r\n _ = wordCount.TryGetValue(searchWord, out var count);\r\n return count;\r\n}\r\n\r\n// csharp_style_unused_value_assignment_preference = unused_local_variable\r\nint GetCount(Dictionary\u003Cstring, int\u003E wordCount, string searchWord)\r\n{\r\n var unused = wordCount.TryGetValue(searchWord, out var count);\r\n return count;\r\n}"}],"Overview":"This rule flags unnecessary value assignments. For example:\r\n// IDE0059: value written to \u0027v\u0027 is never\r\n// read, so assignment to \u0027v\u0027 is unnecessary.\r\nint v = Compute();\r\nv = Compute2();\r\nYou can take one of the following actions to fix this violation:\r\nIf the expression on the right side of the assignment has no side effects, remove the expression or the entire assignment statement. This improves performance by avoiding unnecessary computation.\r\n int v = Compute2();\r\n If the expression on the right side of the assignment has side effects, replace the left side of the assignment with a discard (C# only) or a local variable that\u0027s never used. Discards improve code clarity by explicitly showing the intent to discard an unused value.\r\n _ = Compute();\r\n int v = Compute2();","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":60},"Title":"Remove unused parameter","Category":"Style"}],"Options":[{"Name":"dotnet_code_quality_unused_parameters","Values":[{"Value":"all","Description":"Flag methods with any accessibility that contain unused parameters"},{"Value":"non_public","Description":"Flag only non-public methods that contain unused parameters"}],"DefaultValue":"all","CsharpCodeSample":"// dotnet_code_quality_unused_parameters = all\r\npublic int GetNum1(int unusedParam) { return 1; }\r\ninternal int GetNum2(int unusedParam) { return 1; }\r\nprivate int GetNum3(int unusedParam) { return 1; }\r\n\r\n// dotnet_code_quality_unused_parameters = non_public\r\ninternal int GetNum4(int unusedParam) { return 1; }\r\nprivate int GetNum5(int unusedParam) { return 1; }"}],"Overview":"This rule flags unused parameters.\r\nThis rule does not flag parameters that are named with the discard symbol _. In addition, the rule ignores parameters that are named with the discard symbol followed by an integer, for example, _1. This behavior reduces warning noise on parameters that are needed for signature requirements, for example, a method used as a delegate, a parameter with special attributes, or a parameter whose value is implicitly accessed at run time by a framework but is not referenced in code.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":61},"Title":"Use expression body for local functions","Category":"Style"}],"Options":[{"Name":"csharp_style_expression_bodied_local_functions","Values":[{"Value":"true","Description":"Prefer expression bodies for local functions"},{"Value":"when_on_single_line","Description":"Prefer expression bodies for local functions when they\u0027ll be a single line"},{"Value":"false","Description":"Prefer block bodies for local functions"}],"DefaultValue":"false","CsharpCodeSample":"// csharp_style_expression_bodied_local_functions = true\r\nvoid M()\r\n{\r\n Hello();\r\n void Hello() =\u003E Console.WriteLine(\u0022Hello\u0022);\r\n}\r\n\r\n// csharp_style_expression_bodied_local_functions = false\r\nvoid M()\r\n{\r\n Hello();\r\n void Hello()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n}"}],"Overview":"This style rule concerns the use of expression bodies versus block bodies for local functions. Local functions are private methods of a type that are nested in another member.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":62},"Title":"Make local function static","Category":"Style"}],"Options":[{"Name":"csharp_prefer_static_local_function","Values":[{"Value":"true","Description":"Prefer local functions to be marked static"},{"Value":"false","Description":"Prefer local functions not to be marked static"}],"DefaultValue":"true:suggestion","CsharpCodeSample":"// csharp_prefer_static_local_function = true\r\nvoid M()\r\n{\r\n Hello();\r\n static void Hello()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n}\r\n\r\n// csharp_prefer_static_local_function = false\r\nvoid M()\r\n{\r\n Hello();\r\n void Hello()\r\n {\r\n Console.WriteLine(\u0022Hello\u0022);\r\n }\r\n}"}],"Overview":"This style rule concerns the preference of marking local functions as static or not.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":63},"Title":"Use simple using statement","Category":"Style"}],"Options":[{"Name":"csharp_prefer_simple_using_statement","Values":[{"Value":"true","Description":"Prefer to use a using declaration"},{"Value":"false","Description":"Prefer to use a using statement with curly braces"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_prefer_simple_using_statement = true\r\nusing var a = b;\r\n\r\n// csharp_prefer_simple_using_statement = false\r\nusing (var a = b) { }"}],"Overview":"This style rule concerns the use of using statements without curly braces, also known as using declarations. This alternative syntax was introduced in C# 8.0.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":64},"Title":"Make struct fields writable","Category":"CodeQuality"}],"Options":[],"Overview":"This rule detects structs that contain one or more readonly fields and also contain an assignment to this outside of the constructor. The rule recommends converting readonly fields to non-read only, that is, writable. Marking such struct fields as readonly can lead to unexpected behavior, because the value assigned to the field can change when this is assigned outside the constructor.","Example":"// Code with violations\r\nstruct MyStruct\r\n{\r\n public readonly int Value;\r\n\r\n public MyStruct(int value)\r\n {\r\n Value = value;\r\n }\r\n\r\n public void Test()\r\n {\r\n this = new MyStruct(5);\r\n }\r\n}\r\n\r\n// Fixed code\r\nstruct MyStruct\r\n{\r\n public int Value;\r\n\r\n public MyStruct(int value)\r\n {\r\n Value = value;\r\n }\r\n\r\n public void Test()\r\n {\r\n this = new MyStruct(5);\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":65},"Title":"using directive placement","Category":"Style"}],"Options":[{"Name":"csharp_using_directive_placement","Values":[{"Value":"outside_namespace","Description":"Prefer using directives to be placed outside the namespace"},{"Value":"inside_namespace","Description":"Prefer using directives to be placed inside the namespace"}],"DefaultValue":"outside_namespace","CsharpCodeSample":"// csharp_using_directive_placement = outside_namespace\r\nusing System;\r\n\r\nnamespace Conventions\r\n{\r\n ...\r\n}\r\n\r\n// csharp_using_directive_placement = inside_namespace\r\nnamespace Conventions\r\n{\r\n using System;\r\n ...\r\n}"}],"Overview":"This style rule concerns the preference of placing using directives outside or inside the namespace.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":66},"Title":"Use switch expression","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_switch_expression","Values":[{"Value":"true","Description":"Prefer to use a switch expression"},{"Value":"false","Description":"Prefer to use a switch statement"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_prefer_switch_expression = true\r\nreturn x switch\r\n{\r\n 1 =\u003E 1 * 1,\r\n 2 =\u003E 2 * 2,\r\n _ =\u003E 0,\r\n};\r\n\r\n// csharp_style_prefer_switch_expression = false\r\nswitch (x)\r\n{\r\n case 1:\r\n return 1 * 1;\r\n case 2:\r\n return 2 * 2;\r\n default:\r\n return 0;\r\n}"}],"Overview":"This style rule concerns the use of switch expressions, which were introduced in C# 8.0, versus switch statements.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":70},"Title":"Use System.HashCode.Combine","Category":"Style"}],"Options":[],"Overview":"This rule recommends the use of the System.HashCode.Combine method to compute a hash code instead of using custom hash code computation logic.","Example":"class B\r\n{\r\n public override int GetHashCode() =\u003E 0;\r\n}\r\n\r\nclass C : B\r\n{\r\n int j;\r\n\r\n // Code with violations\r\n public override int GetHashCode()\r\n {\r\n // IDE0070: GetHashCode can be simplified.\r\n var hashCode = 339610899;\r\n hashCode = hashCode * -1521134295 \u002B base.GetHashCode();\r\n hashCode = hashCode * -1521134295 \u002B j.GetHashCode();\r\n return hashCode;\r\n }\r\n\r\n // Fixed code\r\n public override int GetHashCode()\r\n {\r\n return System.HashCode.Combine(base.GetHashCode(), j);\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":71},"Title":"Simplify interpolation","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_simplified_interpolation","Values":[{"Value":"true","Description":"Prefer simplified interpolated strings"},{"Value":"false","Description":"Do not prefer simplified interpolated strings"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_simplified_interpolation = true\r\nvar str = $\u0022prefix {someValue} suffix\u0022;\r\n\r\n// dotnet_style_prefer_simplified_interpolation = false\r\nvar str = $\u0022prefix {someValue.ToString()} suffix\u0022;"}],"Overview":"This style rule concerns with simplification of interpolated strings to improve code readability. It recommends removal of certain explicit method calls, such as ToString(), when the same method would be implicitly invoked by the compiler if the explicit method call is removed.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":72},"Title":"Add missing cases to switch expression","Category":"Style"}],"Options":[],"Overview":"This rule concerns specifying all the missing cases for a switch expression. A switch expression is considered incomplete with missing cases in following scenarios:\r\nWhen an enum switch expression is missing cases for one or more enum members.\r\n When the fall-through case _ is missing.","Example":"enum E\r\n{\r\n A,\r\n B\r\n}\r\n\r\nclass C\r\n{\r\n // Code with violations\r\n int M(E e)\r\n {\r\n // IDE0072: Add missing cases\r\n return e switch\r\n {\r\n E.A =\u003E 0,\r\n _ =\u003E -1,\r\n };\r\n }\r\n\r\n // Fixed code\r\n int M(E e)\r\n {\r\n return e switch\r\n {\r\n E.A =\u003E 0,\r\n E.B =\u003E 1,\r\n _ =\u003E -1,\r\n };\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":73},"Title":"Require file header","Category":"Style"}],"Options":[{"Name":"file_header_template","Values":[{"Value":"non-empty string, optionally containing a {fileName} placeholder","Description":"Prefer the string as the required file header."},{"Value":"unset or empty string","Description":"Do not require a file header."}],"DefaultValue":"unset","CsharpCodeSample":"// file_header_template = Copyright (c) SomeCorp. All rights reserved.\\nLicensed under the xyz license.\r\n\r\n// Copyright (c) SomeCorp. All rights reserved.\r\n// Licensed under the xyz license.\r\nnamespace N1\r\n{\r\n class C1 { }\r\n}\r\n\r\n// file_header_template = unset\r\n// OR\r\n// file_header_template =\r\nnamespace N2\r\n{\r\n class C2 { }\r\n}"}],"Overview":"This style rule concerns providing a file header at top of source code files.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":75},"Title":"Simplify conditional expression","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_simplified_boolean_expressions","Values":[{"Value":"true","Description":"Prefer simplified conditional expressions"},{"Value":"false","Description":"Do not prefer simplified conditional expressions"}],"DefaultValue":"true","CsharpCodeSample":"// dotnet_style_prefer_simplified_boolean_expressions = true\r\nvar result1 = M1() \u0026\u0026 M2();\r\nvar result2 = M1() || M2();\r\n\r\n// dotnet_style_prefer_simplified_boolean_expressions = false\r\nvar result1 = M1() \u0026\u0026 M2() ? true : false;\r\nvar result2 = M1() ? true : M2();"}],"Overview":"This style rule concerns simplifying conditional expressions that return a constant value of true or false versus retaining conditional expressions with explicit true or false return values.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":76},"Title":"Remove invalid global SuppressMessageAttribute","Category":"CodeQuality"}],"Options":[],"Overview":"This rule flags global SuppressMessageAttributes that have an invalid Scope or Target. The attribute should either be removed or fixed to refer to a valid scope and target symbol.","Example":"// IDE0076: Invalid target \u0027~F:N.C.F2\u0027 - no matching field named \u0027F2\u0027\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022member\u0022, Target = \u0022~F:N.C.F2\u0022)]\r\n// IDE0076: Invalid scope \u0027property\u0027\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022property\u0022, Target = \u0022~P:N.C.P\u0022)]\r\n\r\n// Fixed code\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022member\u0022, Target = \u0022~F:N.C.F\u0022)]\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022member\u0022, Target = \u0022~P:N.C.P\u0022)]\r\n\r\nnamespace N\r\n{\r\n class C\r\n {\r\n public int F;\r\n public int P { get; }\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":77},"Title":"Avoid legacy format target in global SuppressMessageAttribute","Category":"CodeQuality"}],"Options":[],"Overview":"This rule flags global SuppressMessageAttributes that specify Target using the legacy FxCop target string format. Using the legacy format Target is known to have performance problems and should be avoided. For more information, see dotnet/roslyn issue 44362.\r\nThe recommended format for Target is the documentation ID format. For information about documentation IDs, see Documentation ID format.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ETip\u003C/p\u003E\r\nVisual Studio 2019 provides a code fix to automatically change the Target of the attribute to the recommended format.","Example":"// IDE0077: Legacy format target \u0027N.C.#F\u0027\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022member\u0022, Target = \u0022N.C.#F\u0022)]\r\n\r\n// Fixed code\r\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\u0022Category\u0022, \u0022Id: Title\u0022, Scope = \u0022member\u0022, Target = \u0022~F:N.C.F\u0022)]\r\n\r\nnamespace N\r\n{\r\n class C\r\n {\r\n public int F;\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":78},"Title":"Use pattern matching","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":260},"Title":"Use pattern matching","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_pattern_matching","Values":[{"Value":"true","Description":"Prefer to use pattern matching constructs, when possible"},{"Value":"false","Description":"Prefer not to use pattern matching constructs."}],"DefaultValue":"true","CsharpCodeSample":null},{"Name":"csharp_style_pattern_matching_over_as_with_null_check","Values":[{"Value":"true","Description":"Prefer pattern matching over as expression with null-conditional member access."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule concerns the use of C# pattern matching constructs.\r\nIDE0260 specifically flags the use of an as expression followed by a member read through the null-conditional operator. This rule is similar to IDE0019, which flags the use of an as expression followed by a null check.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":79},"Title":"Remove unnecessary suppression","Category":"CodeQuality"}],"Options":[{"Name":"dotnet_remove_unnecessary_suppression_exclusions","Values":[{"Value":", separated list of rule IDs or categories (prefixed with category:)","Description":"Excludes suppressions for the listed rules"},{"Value":"all","Description":"Disables the rule (all rule IDs excluded)"},{"Value":"none","Description":"Enables the rule for all rules (no exclusions)"}],"DefaultValue":"none","CsharpCodeSample":"using System.Diagnostics.CodeAnalysis;\r\n\r\nclass C1\r\n{\r\n // \u0027dotnet_remove_unnecessary_suppression_exclusions = IDE0051\u0027\r\n\r\n // Unnecessary pragma suppression, but not flagged by IDE0079\r\n#pragma warning disable IDE0051 // IDE0051: Remove unused member\r\n private int UsedMethod() =\u003E 0;\r\n#pragma warning restore IDE0051\r\n\r\n public int PublicMethod() =\u003E UsedMethod();\r\n}"}],"Overview":"This rule flags unnecessary pragma and System.Diagnostics.CodeAnalysis.SuppressMessageAttribute attribute suppressions in source.\r\nSource suppressions suppress violations of compiler and analyzer rules in specific places but not in other parts of the source code. You generally use them to suppress false positives or less important violations that you don\u0027t intend to fix. However, suppressions often become stale. This can happen if a rule is fixed to prevent false positives or you refactor your code and, in doing so, render the suppressions redundant. This rule helps to identify redundant suppressions, which can be removed.","Example":"using System.Diagnostics.CodeAnalysis;\r\n\r\nclass C1\r\n{\r\n // Necessary pragma suppression\r\n#pragma warning disable IDE0051 // IDE0051: Remove unused member\r\n private int UnusedMethod() =\u003E 0;\r\n#pragma warning restore IDE0051\r\n\r\n // IDE0079: Unnecessary pragma suppression\r\n#pragma warning disable IDE0051 // IDE0051: Remove unused member\r\n private int UsedMethod() =\u003E 0;\r\n#pragma warning restore IDE0051\r\n\r\n public int PublicMethod() =\u003E UsedMethod();\r\n}\r\n\r\nclass C2\r\n{\r\n // Necessary SuppressMessage attribute suppression\r\n [SuppressMessage(\u0022CodeQuality\u0022, \u0022IDE0051:Remove unused private members\u0022, Justification = \u0022\u003CPending\u003E\u0022)]\r\n private int _unusedField;\r\n\r\n // IDE0079: Unnecessary SuppressMessage attribute suppression\r\n [SuppressMessage(\u0022CodeQuality\u0022, \u0022IDE0051:Remove unused private members\u0022, Justification = \u0022\u003CPending\u003E\u0022)]\r\n private int _usedField;\r\n\r\n public int PublicMethod2() =\u003E _usedField;\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":80},"Title":"Remove unnecessary suppression operator","Category":"Style"}],"Options":[],"Overview":"This rule flags an unnecessary suppression or null-forgiving operator. The operator is unnecessary when it\u0027s used in a context where it has no effect. Use of the suppression operator, for example, x!, declares that the expression x of a reference type isn\u0027t null. However, when used in a context of another operator, for example, the is operator in o !is string, it has no effect and can be removed.","Example":"// Code with violations\r\nif (o !is string) { }\r\n\r\n// Potential fixes:\r\n// 1.\r\nif (o is not string) { }\r\n\r\n// 2.\r\nif (!(o is string)) { }\r\n\r\n// 3.\r\nif (o is string) { }"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":81},"Title":"Remove ByVal","Category":"Style"}],"Options":[],"Overview":"This rule flags an unnecessary ByVal keyword in a parameter declaration in Visual Basic. Parameters in Visual Basic are ByVal by default, hence you do not need to explicitly specify it in method signatures. It tends to produce noisy code and often leads to the non-default ByRef keyword being overlooked.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":82},"Title":"Convert typeof to nameof","Category":"Style"}],"Options":[],"Overview":"This style rule recommends use of the nameof operator over the typeof operator followed by System.Reflection.MemberInfo.Name member access. It only fires when the name will be identical in both cases.","Example":"// Code with violations\r\nvar n1 = typeof(T).Name;\r\nvar n2 = typeof(int).Name;\r\n\r\n// Fixed code\r\nvar n1 = nameof(T);\r\nvar n2 = nameof(Int32);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":83},"Title":"Use pattern matching (not operator)","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_not_pattern","Values":[{"Value":"true","Description":"Prefer to use the not pattern, when possible"},{"Value":"false","Description":"Prefer not to use the not pattern."}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_prefer_not_pattern = true\r\nvar y = o is not C c;\r\n\r\n// csharp_style_prefer_not_pattern = false\r\nvar y = !(o is C c);"}],"Overview":"This style rule concerns the use of C# 9.0 not pattern, when possible.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":84},"Title":"Use pattern matching (IsNot operator)","Category":"Style"}],"Options":[],"Overview":"This style rule concerns the use of the Visual Basic 14.0 IsNot pattern, when possible.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":90},"Title":"Simplify new expression","Category":"Style"}],"Options":[{"Name":"csharp_style_implicit_object_creation_when_type_is_apparent","Values":[{"Value":"true","Description":"Prefer target-typed new expressions when created type is apparent"},{"Value":"false","Description":"Do not prefer target-typed new expressions"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_implicit_object_creation_when_type_is_apparent = true\r\nC c = new();\r\nC c2 = new() { Field = 0 };\r\n\r\n// csharp_style_implicit_object_creation_when_type_is_apparent = false\r\nC c = new C();\r\nC c2 = new C() { Field = 0 };"}],"Overview":"This style rule concerns the use of C# 9.0 target-typed new expressions when the created type is apparent.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":100},"Title":"Remove unnecessary equality operator","Category":"Style"}],"Options":[],"Overview":"This style rule flags an unnecessary equality operator when comparing a non-constant Boolean expression with a constant true or false.","Example":"// Code with violations\r\nif (x == true) { }\r\nif (M() != false) { }\r\n\r\n// Fixed code\r\nif (x) { }\r\nif (M()) { }"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":110},"Title":"Remove unnecessary discard","Category":"Style"}],"Options":[],"Overview":"This rule flags unnecessary discard patterns. A discard pattern is unnecessary when used in a context where it has no effect.","Example":"// Code with violations\r\nswitch (o)\r\n{\r\n case int _:\r\n Console.WriteLine(\u0022Value was an int\u0022);\r\n break;\r\n case string _:\r\n Console.WriteLine(\u0022Value was a string\u0022);\r\n break;\r\n}\r\n\r\n// Fixed code\r\nswitch (o)\r\n{\r\n case int:\r\n Console.WriteLine(\u0022Value was an int\u0022);\r\n break;\r\n case string:\r\n Console.WriteLine(\u0022Value was a string\u0022);\r\n break;\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":120},"Title":"Simplify LINQ expression","Category":"Style"}],"Options":[],"Overview":"This rule flags overly complex LINQ expressions, specifically expressions that call System.Linq.Enumerable.Where%60%601(System.Collections.Generic.IEnumerable{%60%600},System.Func{%60%600,System.Int32,System.Boolean}) followed by one of the following methods:\r\nSystem.Linq.Enumerable.Any%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.Count%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.First%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.FirstOrDefault%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.Last%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.LastOrDefault%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.Single%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\n System.Linq.Enumerable.SingleOrDefault%60%601(System.Collections.Generic.IEnumerable{%60%600})\r\nSuch expressions can be simplified by removing the call to System.Linq.Enumerable.Where%60%601(System.Collections.Generic.IEnumerable{%60%600},System.Func{%60%600,System.Int32,System.Boolean}) and instead calling an overload of Any(), Count(), First(), FirstOrDefault(), Last(), LastOrDefault(), Single, or SingleOrDefault() that accepts a predicate function to filter the elements.","Example":"// Code with violations.\r\nIEnumerable\u003Cstring\u003E words = new List\u003Cstring\u003E { \u0022hello\u0022, \u0022world\u0022, \u0022!\u0022 };\r\nvar result = words.Where(x =\u003E x.Equals(\u0022hello\u0022)).Any();\r\n\r\n// Fixed code.\r\nIEnumerable\u003Cstring\u003E words = new List\u003Cstring\u003E { \u0022hello\u0022, \u0022world\u0022, \u0022!\u0022 };\r\nvar result = words.Any(x =\u003E x.Equals(\u0022hello\u0022));"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":130},"Title":"Namespace does not match folder structure","Category":"Style"}],"Options":[{"Name":"dotnet_style_namespace_match_folder","Values":[{"Value":"true","Description":"Prefer namespace naming to match folder structure."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule uses the folder structure of the project to enforce namespace naming requirements.","Example":"// Code with violations\r\nnamespace Root.BadExample\r\n{\r\n class Example\r\n {\r\n public void M()\r\n {\r\n }\r\n }\r\n}\r\n\r\n// Fixed code\r\nnamespace Root.Data\r\n{\r\n class Example\r\n {\r\n public void M()\r\n {\r\n }\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":140},"Title":"Simplify object creation","Category":"Style"}],"Options":[],"Overview":"This style rule flags unnecessary type repetition in Visual Basic code.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":150},"Title":"Prefer null check over type check","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_null_check_over_type_check","Values":[{"Value":"true","Description":"Prefer null check over type check."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule flags use of the is {type} statement when is not null can be used instead. Similarly, it flags use of the is not {type} statement in favor of is null. Using is null or is not null improves code readability.","Example":"// Violates IDE0150.\r\nif (numbers is not IEnumerable\u003Cint\u003E) ...\r\n\r\n// Fixed code.\r\nif (numbers is null) ..."},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":160},"Title":"Use block-scoped namespace","Category":"Style"},{"RuleId":{"RuleType":"IDE","Id":161},"Title":"Use file-scoped namespace","Category":"Style"}],"Options":[{"Name":"csharp_style_namespace_declarations","Values":[{"Value":"block_scoped","Description":"Namespace declarations should be block scoped."},{"Value":"file_scoped","Description":"Namespace declarations should be file scoped."}],"DefaultValue":"block_scoped","CsharpCodeSample":"// csharp_style_namespace_declarations = block_scoped\r\nusing System;\r\n\r\nnamespace Convention\r\n{\r\n class C\r\n {\r\n }\r\n}\r\n\r\n// csharp_style_namespace_declarations = file_scoped\r\nusing System;\r\n\r\nnamespace Convention;\r\nclass C\r\n{\r\n}"}],"Overview":"These rules apply to namespace declarations. For IDE0161 to report violations when block-scoped namespaces are used, you must set the associated option to file_scoped.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":170},"Title":"Simplify property pattern","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_extended_property_pattern","Values":[{"Value":"true","Description":"Prefer the extended property pattern."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule flags the use of a nested pattern in a property pattern. A nested pattern can be simplified to use an extended property pattern in which property subpatterns are used to reference nested members. Extended property patterns improve code readability.","Example":"public record Point(int X, int Y);\r\npublic record Segment(Point Start, Point End);\r\n\r\n// Violates IDE0170.\r\nstatic bool IsEndOnXAxis(Segment segment) =\u003E\r\n segment is { Start: { Y: 0 } } or { End: { Y: 0 } };\r\n\r\n// Fixed code.\r\nstatic bool IsEndOnXAxis(Segment segment) =\u003E\r\n segment is { Start.Y: 0 } or { End.Y: 0 };"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":180},"Title":"Use tuple to swap values","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_tuple_swap","Values":[{"Value":"true","Description":"Prefer using a tuple to swap two values."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This style rule flags code that swaps two values using multiple lines of code instead of using a tuple.","Example":"List\u003Cint\u003E numbers = new List\u003Cint\u003E() { 5, 6, 4 };\r\n\r\n// Violates IDE0180.\r\nint temp = numbers[0];\r\nnumbers[0] = numbers[1];\r\nnumbers[1] = temp;\r\n\r\n// Fixed code.\r\n(numbers[1], numbers[0]) = (numbers[0], numbers[1]);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":200},"Title":"Remove unnecessary lambda expression","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_method_group_conversion","Values":[{"Value":"true","Description":"Prefer to convert a lambda expression to a method group."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags the use of a lambda expression where it\u0027s unnecessary. Lambda expressions might be unnecessary when the following are all true:\r\nThe expression includes a method invocation.\r\n The lambda expression has the same number and order of parameters as the method invocation.\r\n The method invocation has no side effects.\r\n The lambda expression isn\u0027t assigned to a non-delegate type.\r\n If the invocation is a generic method, the type arguments are supplied.\r\n The invoked method\u0027s return type can be converted to the lambda expression\u0027s return type.\r\n There\u0027s only one applicable method in the method group.","Example":"// Code with violations.\r\nbool IsEven(int x) =\u003E x % 2 == 0;\r\n_ = new[] { 1, 2, 3 }.Where(n =\u003E IsEven(n));\r\n\r\n// Fixed code.\r\nbool IsEven(int x) =\u003E x % 2 == 0;\r\n_ = new[] { 1, 2, 3 }.Where(IsEven);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":210},"Title":"Convert to top-level statements","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_top_level_statements","Values":[{"Value":"true","Description":"Prefer top-level statements."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags the use of a Main method entry point in a project that could be converted to top-level statements instead. A candidate method must meet the following requirements:\r\nIs static.\r\n Is named Main.\r\n Has a method body.\r\n Has no type parameters.\r\n Is contained in a type that\u0027s not public, doesn\u0027t derive from another type or implement an interface, isn\u0027t a nested type, and has no attributes or documentation comments.","Example":"// Code with violations.\r\ninternal class Program\r\n{\r\n private static void Main(string[] args)\r\n {\r\n Console.WriteLine(\u0022Hello world.\u0022);\r\n }\r\n}\r\n\r\n// Fixed code.\r\nConsole.WriteLine(\u0022Hello world.\u0022);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":211},"Title":"Convert to \u0027Program.Main\u0027 style program","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_top_level_statements","Values":[{"Value":"true","Description":"Disables the rule."},{"Value":"false","Description":"Prefer Program.Main style program."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags the use of top-level statements instead of a Main method entry point in a project.","Example":"// Code with violations (entire file).\r\nConsole.WriteLine(\u0022Hello world.\u0022);\r\n\r\n// Fixed code.\r\ninternal class Program\r\n{\r\n private static void Main(string[] args)\r\n {\r\n Console.WriteLine(\u0022Hello world.\u0022);\r\n }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":220},"Title":"Add explicit cast","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_foreach_explicit_cast_in_source","Values":[{"Value":"always","Description":"Prefer explicit casts in source code."},{"Value":"when_strongly_typed","Description":"Prefer explicit casts for strongly typed (generic) collections but not for legacy collections, such as System.Collections.ArrayList."}],"DefaultValue":"when_strongly_typed","CsharpCodeSample":null}],"Overview":"This rule flags the absence of an explicit cast in a foreach loop when the compiler would add a hidden cast. For generic, or strongly typed, collections, forcing an explicit cast when the compiler would add a hidden cast can uncover the use of an incorrect type in the foreach statement.","Example":"// Code with violations.\r\nvar list = new List\u003Cobject\u003E();\r\nforeach (string item in list) { }\r\n\r\n// Fixed code.\r\nvar list = new List\u003Cobject\u003E();\r\nforeach (string item in list.Cast\u003Cstring\u003E())"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":230},"Title":"Use UTF-8 string literal","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_utf8_string_literals","Values":[{"Value":"true","Description":"Prefer UTF-8 string literals to byte arrays."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags the use of a byte array (byte[]) where a UTF-8 string literal could be used instead. Using a UTF-8 string literal adds clarity to the declaration.","Example":"// Code with violations.\r\nReadOnlySpan\u003Cbyte\u003E _ = new byte[] { 65, 66, 67 };\r\n\r\n// Fixed code.\r\nReadOnlySpan\u003Cbyte\u003E _ = \u0022ABC\u0022u8;"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":240},"Title":"Nullable directive is redundant","Category":"Style"}],"Options":[],"Overview":"This rule flags places where a #nullable directive is redundant. For example:\r\n#nullable enable following another #nullable enable with no disablement in between.\r\n #nullable enable in a project where nullable context is already enabled and hasn\u0027t been disabled.\r\n #nullable restore following another #nullable restore with no nullability context change in between.\r\n #nullable restore in a place that already matches the project context.","Example":"// Code with violations (in a project with \u003CNullable\u003Eenable\u003C/Nullable\u003E).\r\n#nullable enable\r\nConsole.WriteLine(\u0022Hello world.\u0022);\r\n\r\n// Fixed code.\r\nConsole.WriteLine(\u0022Hello world.\u0022);"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":241},"Title":"Nullable directive is unnecessary","Category":"Style"}],"Options":[],"Overview":"This rule flags places where a #nullable directive is unnecessary. The directive is unnecessary where there are no reference types that would be impacted by the nullable context scope change. For example:\r\n#nullable enable in a project where nullable context is already enabled.\r\n #nullable disable in a project where nullable context is already disabled.\r\n #nullable disable for an enumeration.\r\n #nullable disable or #nullable restore at the end of a file that includes #nullable enable in a project where nullable context is disabled.","Example":"// Code with violations (in a project with \u003CNullable\u003Eenable\u003C/Nullable\u003E).\r\n#nullable disable\r\nenum Place\r\n{\r\n First,\r\n Second\r\n}\r\n\r\n// Fixed code.\r\nenum Place\r\n{\r\n First,\r\n Second\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":250},"Title":"Struct can be made \u0027readonly\u0027","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_readonly_struct","Values":[{"Value":"true","Description":"Prefer to make a struct readonly when all its fields are readonly."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags structs that aren\u0027t marked readonly when all their members are marked readonly.","Example":"// Code with violations.\r\nstruct S\r\n{\r\n readonly int i;\r\n}\r\n\r\n// Fixed code.\r\nreadonly struct S\r\n{\r\n readonly int i;\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":251},"Title":"Member can be made \u0027readonly\u0027","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_readonly_struct_member","Values":[{"Value":"true","Description":"Prefer to make struct members readonly."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags members of non-readonly structs that aren\u0027t marked readonly that could be marked as readonly.","Example":"// Code with violations.\r\nstruct S\r\n{\r\n void M() { }\r\n}\r\n\r\n// Fixed code.\r\nstruct S\r\n{\r\n readonly void M() { }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":280},"Title":"Use \u0027nameof\u0027","Category":"Style"}],"Options":[],"Overview":"This rule flags the use of a literal parameter name instead of the nameof expression in attributes such as System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute, System.Diagnostics.CodeAnalysis.NotNullWhenAttribute, and System.Runtime.CompilerServices.CallerArgumentExpressionAttribute that take a parameter name.","Example":"// Code with violations.\r\nclass C\r\n{\r\n void M([NotNullIfNotNull(\u0022input\u0022)] string? input) { }\r\n}\r\n\r\n// Fixed code.\r\nclass C\r\n{\r\n void M([NotNullIfNotNull(nameof(input))] string? input) { }\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":290},"Title":"Use primary constructor","Category":"Style"}],"Options":[{"Name":"csharp_style_prefer_primary_constructors","Values":[{"Value":"true","Description":"Prefer to use primary constructors."},{"Value":"false","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule flags classes that can use a primary constructor instead of a separate constructor definition. You define a primary constructor by placing any constructor parameters in parentheses following the type name. A primary constructor indicates that these parameters are necessary for any instance of the type.","Example":"// Code with violations.\r\nclass C\r\n{\r\n public C(int i) { }\r\n}\r\n\r\n// Fixed code.\r\nclass C(int i)\r\n{\r\n}"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":300},"Title":"Use collection expression for array","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions only when types match exactly, for example, int[] i = new int[] { 1, 2, 3 };."},{"Value":"when_types_loosely_match(.NET 9 and later versions)*","Description":"Prefer to use collection expressions even when types match loosely, for example, IEnumerable\u003Cint\u003E i = new int[] { 1, 2, 3 };. The targeted type must match the type on the right-hand side or be one of the following types: System.Collections.Generic.IEnumerable%601, System.Collections.Generic.ICollection%601, System.Collections.Generic.IList%601, System.Collections.Generic.IReadOnlyCollection%601, System.Collections.Generic.IReadOnlyList%601."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true in .NET 8when_types_loosely_match in .NET 9 and later versions","CsharpCodeSample":null}],"Overview":"This rule flags places where a collection expression could be used to initialize an array. For example, this rule offers to simplify code like new C[] { ... }, new[] { ... }, and C[] c = { ... } into the collection expression form ([...]).","Example":"// Code with violations.\r\nint[] i = new int[] { 1, 2, 3 };\r\nIEnumerable\u003Cint\u003E j = new int[] { 1, 2, 3 };\r\n\r\n// Fixed code.\r\nint[] i = [1, 2, 3];\r\nIEnumerable\u003Cint\u003E j = [1, 2, 3];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":301},"Title":"Use collection expression for empty","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions only when types match exactly, for example, int[] i = Array.Empty\u003Cint\u003E();."},{"Value":"when_types_loosely_match(.NET 9 and later versions)*","Description":"Prefer to use collection expressions even when types match loosely, for example, IEnumerable\u003Cint\u003E i = Array.Empty\u003Cint\u003E();. The targeted type must match the type on the right-hand side or be one of the following types: System.Collections.Generic.IEnumerable%601, System.Collections.Generic.ICollection%601, System.Collections.Generic.IList%601, System.Collections.Generic.IReadOnlyCollection%601, System.Collections.Generic.IReadOnlyList%601."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true in .NET 8when_types_loosely_match in .NET 9 and later versions","CsharpCodeSample":null}],"Overview":"This rule looks for code similar to Array.Empty\u003CT\u003E() (a method call that returns an empty collection) or ImmutableArray\u003CT\u003E.Empty (a property that returns an empty collection) and offers to replace it with a collection expression ([]).","Example":"// Code with violations.\r\nint[] i = Array.Empty\u003Cint\u003E();\r\nIEnumerable\u003Cint\u003E j = Array.Empty\u003Cint\u003E();\r\nReadOnlySpan\u003Cint\u003E span = ReadOnlySpan\u003Cint\u003E.Empty;\r\n\r\n// Fixed code.\r\nint[] i = [];\r\nIEnumerable\u003Cint\u003E j = [];\r\nReadOnlySpan\u003Cint\u003E span = [];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":302},"Title":"Use collection expression for stackalloc","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true","CsharpCodeSample":null}],"Overview":"This rule is similar to Use collection expression for array (IDE0300) except it looks for stackalloc instead of arrays. Like IDE0300, it offers to convert the code to use a collection expression. For example, stackalloc int[] { ... } and stackalloc [] { ... } are simplified to [...].\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule is only available in .NET 8 and later versions where the values can be preserved on the stack.","Example":"// Code with violations.\r\nReadOnlySpan\u003Cint\u003E x = stackalloc int[] { 1, 2, 3 };\r\n\r\n// Fixed code.\r\nReadOnlySpan\u003Cint\u003E x = [1, 2, 3];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":303},"Title":"Use collection expression for Create","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions only when types match exactly, for example, ImmutableArray\u003Cint\u003E i = ImmutableArray.Create(1, 2, 3);."},{"Value":"when_types_loosely_match(.NET 9 and later versions)*","Description":"Prefer to use collection expressions even when types match loosely, for example, IEnumerable\u003Cint\u003E i = ImmutableArray.Create(1, 2, 3);. The targeted type must match the type on the right-hand side or be one of the following types: System.Collections.Generic.IEnumerable%601, System.Collections.Generic.ICollection%601, System.Collections.Generic.IList%601, System.Collections.Generic.IReadOnlyCollection%601, System.Collections.Generic.IReadOnlyList%601."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true in .NET 8when_types_loosely_match in .NET 9 and later versions","CsharpCodeSample":null}],"Overview":"This rule flags places where a Create() method or a similar method that\u0027s designated as the collection construction method (using the System.Runtime.CompilerServices.CollectionBuilderAttribute attribute) is used to initialize a collection and offers to replace it with a collection expression ([...]).\r\nCreate() methods are common for the immutable collections, for example, ImmutableArray.Create(1, 2, 3).\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule requires more recent versions of the immutable APIs (for example, System.Collections.Immutable), which opt into the collection-expression pattern.","Example":"// Code with violations.\r\nImmutableArray\u003Cint\u003E i = ImmutableArray.Create(1, 2, 3);\r\nIEnumerable\u003Cint\u003E j = ImmutableArray.Create(1, 2, 3);\r\n\r\n// Fixed code.\r\nImmutableArray\u003Cint\u003E i = [1, 2, 3];\r\nIEnumerable\u003Cint\u003E j = [1, 2, 3];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":304},"Title":"Use collection expression for builder","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions only when types match exactly."},{"Value":"when_types_loosely_match(.NET 9 and later versions)*","Description":"Prefer to use collection expressions even when types match loosely. The targeted type must match the type on the right-hand side or be one of the following types: System.Collections.Generic.IEnumerable%601, System.Collections.Generic.ICollection%601, System.Collections.Generic.IList%601, System.Collections.Generic.IReadOnlyCollection%601, System.Collections.Generic.IReadOnlyList%601."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true in .NET 8when_types_loosely_match in .NET 9 and later versions","CsharpCodeSample":null}],"Overview":"This rule flags places where a CreateBuilder() or similar method is called to create a builder type that adds elements and finally constructs a collection type that has the System.Runtime.CompilerServices.CollectionBuilderAttribute attribute (for example, by calling System.Collections.Immutable.ImmutableArray%601.Builder.ToImmutable). Instead, a collection expression ([...]) could be used to initialize the collection.\r\n\u003Cp class=\u0022markdown-alert-title\u0022\u003E\u003Csvg viewBox=\u00220 0 16 16\u0022 version=\u00221.1\u0022 width=\u002216\u0022 height=\u002216\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z\u0022\u003E\u003C/path\u003E\u003C/svg\u003ENote\u003C/p\u003E\r\nThis rule requires more recent versions of the immutable APIs (for example, System.Collections.Immutable), which opt into the collection-expression pattern.","Example":"// Code with violation.\r\nvar builder = ImmutableArray.CreateBuilder\u003Cint\u003E();\r\nbuilder.Add(1);\r\nbuilder.AddRange(new int[] { 5, 6, 7 });\r\nImmutableArray\u003Cint\u003E i = builder.ToImmutable();\r\n\r\n// Fixed code.\r\nImmutableArray\u003Cint\u003E i = [1, .. new int[] { 5, 6, 7 }];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":305},"Title":"Use collection expression for fluent","Category":"Style"}],"Options":[{"Name":"dotnet_style_prefer_collection_expression","Values":[{"Value":"true | when_types_exactly_match","Description":"Prefer to use collection expressions only when types match exactly, for example, List\u003Cint\u003E list = new[] { 1, 2, 3 }.ToList();."},{"Value":"when_types_loosely_match(.NET 9 and later versions)*","Description":"Prefer to use collection expressions even when types match loosely, for example, IEnumerable\u003Cint\u003E list = new[] { 1, 2, 3 }.ToList();. The targeted type must match the type on the right-hand side or be one of the following types: System.Collections.Generic.IEnumerable%601, System.Collections.Generic.ICollection%601, System.Collections.Generic.IList%601, System.Collections.Generic.IReadOnlyCollection%601, System.Collections.Generic.IReadOnlyList%601."},{"Value":"false | never","Description":"Disables the rule."}],"DefaultValue":"true in .NET 8when_types_loosely_match in .NET 9 and later versions","CsharpCodeSample":null}],"Overview":"This rule flags places where a collection is built in a fluent manner, that is, where methods like Add(), AddRange(), AsSpan(), ToList(), and ToArray() are chained. Instead, a collection expression could be used to initialize the collection. For example, x.AddRange(y).Add(z).AsSpan() is converted to [x, ..y, z].","Example":"// Code with violation.\r\nList\u003Cint\u003E i = new[] { 1, 2, 3 }.ToList();\r\nIEnumerable\u003Cint\u003E j = new[] { 1, 2, 3 }.ToList();\r\n\r\n// Fixed code.\r\nList\u003Cint\u003E i = [1, 2, 3];\r\nIEnumerable\u003Cint\u003E j = [1, 2, 3];"},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":1005},"Title":"Use conditional delegate call","Category":"Style"}],"Options":[{"Name":"csharp_style_conditional_delegate_call","Values":[{"Value":"true","Description":"Prefer to use the conditional coalescing operator (?.) when invoking a lambda expression"},{"Value":"false","Description":"Prefer to perform a null check before invoking a lambda expression"}],"DefaultValue":"true","CsharpCodeSample":"// csharp_style_conditional_delegate_call = true\r\nfunc?.Invoke(args);\r\n\r\n// csharp_style_conditional_delegate_call = false\r\nif (func != null) { func(args); }"}],"Overview":"This style rule concerns the use of the null-conditional operator (?.) when invoking a lambda expression, as opposed to performing a null check.","Example":null},{"Rules":[{"RuleId":{"RuleType":"IDE","Id":1006},"Title":"Code-style naming rules","Category":"Style"}],"Options":[],"Overview":"","Example":null}]} \ No newline at end of file diff --git a/Sources/Kysect.Configuin.Console/Commands/AnalyzeEditorConfigCommand.cs b/Sources/Kysect.Configuin.Console/Commands/AnalyzeEditorConfigCommand.cs index 0e076ae..0f9b75b 100644 --- a/Sources/Kysect.Configuin.Console/Commands/AnalyzeEditorConfigCommand.cs +++ b/Sources/Kysect.Configuin.Console/Commands/AnalyzeEditorConfigCommand.cs @@ -33,15 +33,17 @@ public sealed class Settings : CommandSettings public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings) { settings.EditorConfigPath.ThrowIfNull(); - settings.MsLearnRepositoryPath.ThrowIfNull(); EditorConfigAnalyzer editorConfigAnalyzer = new EditorConfigAnalyzer(); IEditorConfigAnalyzeReporter reporter = new EditorConfigAnalyzeLogReporter(logger); + RoslynRules roslynRules = settings.MsLearnRepositoryPath is null + ? RoslynRuleDocumentationCache.ReadFromCache() + : roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + string editorConfigContent = File.ReadAllText(settings.EditorConfigPath); EditorConfigDocument editorConfigDocument = editorConfigDocumentParser.Parse(editorConfigContent); DotnetConfigSettings dotnetConfigSettings = dotnetConfigSettingsParser.Parse(editorConfigDocument); - RoslynRules roslynRules = roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); EditorConfigMissedConfiguration editorConfigMissedConfiguration = editorConfigAnalyzer.GetMissedConfigurations(dotnetConfigSettings, roslynRules); IReadOnlyCollection incorrectOptionValues = editorConfigAnalyzer.GetIncorrectOptionValues(dotnetConfigSettings, roslynRules); diff --git a/Sources/Kysect.Configuin.Console/Commands/FormatEditorconfigCommand.cs b/Sources/Kysect.Configuin.Console/Commands/FormatEditorconfigCommand.cs index a366731..7cb5021 100644 --- a/Sources/Kysect.Configuin.Console/Commands/FormatEditorconfigCommand.cs +++ b/Sources/Kysect.Configuin.Console/Commands/FormatEditorconfigCommand.cs @@ -34,10 +34,11 @@ public sealed class Settings : CommandSettings public override int Execute(CommandContext context, Settings settings) { settings.EditorConfigPath.ThrowIfNull(); - settings.MsLearnRepositoryPath.ThrowIfNull(); string[] editorConfigContentLines = File.ReadAllLines(settings.EditorConfigPath); - RoslynRules roslynRules = roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + RoslynRules roslynRules = settings.MsLearnRepositoryPath is null + ? RoslynRuleDocumentationCache.ReadFromCache() + : roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); EditorConfigDocument editorConfigDocument = editorConfigDocumentParser.Parse(editorConfigContentLines); EditorConfigDocument formattedDocument = editorConfigFormatter.FormatAccordingToRuleDefinitions(editorConfigDocument, roslynRules, settings.GroupQualityRulesByCategory); diff --git a/Sources/Kysect.Configuin.Console/Commands/GenerateCodeStyleDocCommand.cs b/Sources/Kysect.Configuin.Console/Commands/GenerateCodeStyleDocCommand.cs index 747d881..0982b55 100644 --- a/Sources/Kysect.Configuin.Console/Commands/GenerateCodeStyleDocCommand.cs +++ b/Sources/Kysect.Configuin.Console/Commands/GenerateCodeStyleDocCommand.cs @@ -38,14 +38,15 @@ public sealed class Settings : CommandSettings public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings) { settings.EditorConfigPath.ThrowIfNull(); - settings.MsLearnRepositoryPath.ThrowIfNull(); settings.OutputPath.ThrowIfNull(); string editorConfigContent = File.ReadAllText(settings.EditorConfigPath); EditorConfigDocument editorConfigDocument = documentParser.Parse(editorConfigContent); DotnetConfigSettings dotnetConfigSettings = dotnetConfigSettingsParser.Parse(editorConfigDocument); - RoslynRules roslynRules = roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + RoslynRules roslynRules = settings.MsLearnRepositoryPath is null + ? RoslynRuleDocumentationCache.ReadFromCache() + : roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); CodeStyle codeStyle = codeStyleGenerator.Generate(dotnetConfigSettings, roslynRules); codeStyleWriter.Write(settings.OutputPath, codeStyle); diff --git a/Sources/Kysect.Configuin.Console/Commands/GenerateEditorConfigTemplateTemplate.cs b/Sources/Kysect.Configuin.Console/Commands/GenerateEditorConfigTemplateTemplate.cs index 0e23fa7..cf45a0a 100644 --- a/Sources/Kysect.Configuin.Console/Commands/GenerateEditorConfigTemplateTemplate.cs +++ b/Sources/Kysect.Configuin.Console/Commands/GenerateEditorConfigTemplateTemplate.cs @@ -29,9 +29,11 @@ public sealed class Settings : CommandSettings public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings) { settings.EditorConfigPath.ThrowIfNull(); - settings.MsLearnRepositoryPath.ThrowIfNull(); - RoslynRules roslynRules = roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + RoslynRules roslynRules = settings.MsLearnRepositoryPath is null + ? RoslynRuleDocumentationCache.ReadFromCache() + : roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + string editorconfigContent = editorConfigTemplateGenerator.GenerateTemplate(roslynRules); // TODO: move to interface? logger.LogInformation("Writing .editorconfig template to {path}", settings.EditorConfigPath); diff --git a/Sources/Kysect.Configuin.Console/Commands/GenerateRoslynRuleDocumentationFile.cs b/Sources/Kysect.Configuin.Console/Commands/GenerateRoslynRuleDocumentationFile.cs new file mode 100644 index 0000000..24cdb5e --- /dev/null +++ b/Sources/Kysect.Configuin.Console/Commands/GenerateRoslynRuleDocumentationFile.cs @@ -0,0 +1,36 @@ +using Kysect.CommonLib.BaseTypes.Extensions; +using Kysect.Configuin.Learn.Abstraction; +using Kysect.Configuin.RoslynModels; +using Spectre.Console.Cli; +using System.ComponentModel; +using System.Text.Json; + +namespace Kysect.Configuin.Console.Commands; + +public class GenerateRoslynRuleDocumentationFile( + IRoslynRuleDocumentationParser roslynRuleDocumentationParser +) : Command +{ + public sealed class Settings : CommandSettings + { + [Description("Path to cloned MS Learn repository.")] + [CommandArgument(0, "[ms-repo-path]")] + public string? MsLearnRepositoryPath { get; init; } + + [Description("Output path.")] + [CommandArgument(0, "[output-path]")] + public string? OutputPath { get; init; } + } + + public override int Execute(CommandContext context, Settings settings) + { + settings.ThrowIfNull(); + settings.MsLearnRepositoryPath.ThrowIfNull(); + settings.OutputPath.ThrowIfNull(); + + RoslynRules roslynRules = roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath); + string documentation = JsonSerializer.Serialize(roslynRules); + File.WriteAllText(settings.OutputPath, documentation); + return 0; + } +} \ No newline at end of file diff --git a/Sources/Kysect.Configuin.Console/Program.cs b/Sources/Kysect.Configuin.Console/Program.cs index c4f03f6..b231faf 100644 --- a/Sources/Kysect.Configuin.Console/Program.cs +++ b/Sources/Kysect.Configuin.Console/Program.cs @@ -25,6 +25,7 @@ public static void Main(string[] args) config.AddCommand("analyze"); config.AddCommand("template"); config.AddCommand("format"); + config.AddCommand("generate-roslyn-documentation"); }); app.Run(args); @@ -37,7 +38,8 @@ private static string[] PrepareTestCommand() string[] analyzeCommand = new[] { "analyze", ".editorconfig", "-d", msLearnRepositoryPath }; string[] templateGenerateCommand = new[] { "template", ".editorconfig", "-d", msLearnRepositoryPath }; string[] formatCommand = new[] { "format", ".editorconfig", "-d", msLearnRepositoryPath }; + string[] generateRoslynDocumentationCommand = new[] { "generate-roslyn-documentation", msLearnRepositoryPath, "roslyn-rules.json" }; - return formatCommand; + return generateRoslynDocumentationCommand; } } \ No newline at end of file diff --git a/Sources/Kysect.Configuin.Console/RoslynRuleDocumentationCache.cs b/Sources/Kysect.Configuin.Console/RoslynRuleDocumentationCache.cs new file mode 100644 index 0000000..c22abd3 --- /dev/null +++ b/Sources/Kysect.Configuin.Console/RoslynRuleDocumentationCache.cs @@ -0,0 +1,21 @@ +using Kysect.CommonLib.BaseTypes.Extensions; +using Kysect.Configuin.Common; +using Kysect.Configuin.RoslynModels; +using System.Text.Json; + +namespace Kysect.Configuin.Console; + +public static class RoslynRuleDocumentationCache +{ + public static RoslynRules ReadFromCache() + { + var fileName = "roslyn-rules.json"; + if (!File.Exists(fileName)) + { + throw new ConfiguinException($"File with {fileName} was not found"); + } + + string readAllText = File.ReadAllText(fileName); + return JsonSerializer.Deserialize(readAllText).ThrowIfNull(); + } +} \ No newline at end of file diff --git a/Sources/Kysect.Configuin.EditorConfig/Analyzing/EditorConfigAnalyzer.cs b/Sources/Kysect.Configuin.EditorConfig/Analyzing/EditorConfigAnalyzer.cs index 570134a..8a67920 100644 --- a/Sources/Kysect.Configuin.EditorConfig/Analyzing/EditorConfigAnalyzer.cs +++ b/Sources/Kysect.Configuin.EditorConfig/Analyzing/EditorConfigAnalyzer.cs @@ -25,7 +25,7 @@ public EditorConfigMissedConfiguration GetMissedConfigurations(DotnetConfigSetti .ToHashSet(); var missedStyleRules = roslynRules - .StyleRules + .GetStyleRules() .Where(rule => !selectedSeverity.Contains(rule.RuleId)) .Select(r => r.RuleId) .Order() @@ -74,7 +74,7 @@ public IReadOnlyCollection GetIncorrectOptionSeverity(DotnetConfig ArgumentNullException.ThrowIfNull(roslynRules); var ruleIds = new HashSet(); - ruleIds.AddEach(roslynRules.StyleRules.Select(r => r.RuleId)); + ruleIds.AddEach(roslynRules.GetStyleRules().Select(r => r.RuleId)); ruleIds.AddEach(roslynRules.QualityRules.Select(r => r.RuleId)); var result = new List(); diff --git a/Sources/Kysect.Configuin.Learn/LearnDocumentationParser.cs b/Sources/Kysect.Configuin.Learn/LearnDocumentationParser.cs index b770c1a..e1851e0 100644 --- a/Sources/Kysect.Configuin.Learn/LearnDocumentationParser.cs +++ b/Sources/Kysect.Configuin.Learn/LearnDocumentationParser.cs @@ -56,7 +56,7 @@ public RoslynRules Parse(string learnRepositoryPath) private List AddNamingRule(List roslynStyleRules) { var namingRule = new RoslynStyleRule(RoslynNameRuleInfo.RuleId, "Code-style naming rules", "Style"); - var roslynStyleRuleGroup = new RoslynStyleRuleGroup(namingRule, string.Empty, null); + var roslynStyleRuleGroup = new RoslynStyleRuleGroup([namingRule], [], string.Empty, null); roslynStyleRules.Add(roslynStyleRuleGroup); return roslynStyleRules; diff --git a/Sources/Kysect.Configuin.RoslynModels/RoslynRules.cs b/Sources/Kysect.Configuin.RoslynModels/RoslynRules.cs index c757f5d..f37c3c9 100644 --- a/Sources/Kysect.Configuin.RoslynModels/RoslynRules.cs +++ b/Sources/Kysect.Configuin.RoslynModels/RoslynRules.cs @@ -1,19 +1,12 @@ namespace Kysect.Configuin.RoslynModels; -public class RoslynRules +public record RoslynRules( + IReadOnlyCollection QualityRules, + IReadOnlyCollection StyleRuleGroups) { - public IReadOnlyCollection QualityRules { get; } - public IReadOnlyCollection StyleRules { get; } - public IReadOnlyCollection StyleRuleGroups { get; } - - public RoslynRules( - IReadOnlyCollection qualityRules, - IReadOnlyCollection styleRuleGroups) + public IReadOnlyCollection GetStyleRules() { - QualityRules = qualityRules; - StyleRuleGroups = styleRuleGroups; - - StyleRules = styleRuleGroups.SelectMany(r => r.Rules).ToList(); + return StyleRuleGroups.SelectMany(r => r.Rules).ToList(); } public IReadOnlyCollection GetOptions() diff --git a/Sources/Kysect.Configuin.RoslynModels/RoslynStyleRuleGroup.cs b/Sources/Kysect.Configuin.RoslynModels/RoslynStyleRuleGroup.cs index cf2064e..6250cfd 100644 --- a/Sources/Kysect.Configuin.RoslynModels/RoslynStyleRuleGroup.cs +++ b/Sources/Kysect.Configuin.RoslynModels/RoslynStyleRuleGroup.cs @@ -4,22 +4,4 @@ public record RoslynStyleRuleGroup( IReadOnlyCollection Rules, IReadOnlyCollection Options, string Overview, - string? Example) -{ - public RoslynStyleRuleGroup( - RoslynStyleRule rule, - string Overview, - string? Example) - : this(new[] { rule }, Array.Empty(), Overview, Example) - { - } - - public RoslynStyleRuleGroup( - RoslynStyleRule rule, - IReadOnlyCollection Options, - string Overview, - string? Example) - : this(new[] { rule }, Options, Overview, Example) - { - } -} \ No newline at end of file + string? Example); \ No newline at end of file diff --git a/Sources/Kysect.Configuin.Tests/Resources/WellKnownRoslynRuleDefinitions.cs b/Sources/Kysect.Configuin.Tests/Resources/WellKnownRoslynRuleDefinitions.cs index ee90aae..1d5cd77 100644 --- a/Sources/Kysect.Configuin.Tests/Resources/WellKnownRoslynRuleDefinitions.cs +++ b/Sources/Kysect.Configuin.Tests/Resources/WellKnownRoslynRuleDefinitions.cs @@ -25,7 +25,8 @@ class C Category: "Style"); return new RoslynStyleRuleGroup( - rule, + [rule], + [], Overview: overview, Example: example); } @@ -114,7 +115,7 @@ class MyClass "Add accessibility modifiers", "Style"); - return new RoslynStyleRuleGroup(styleRule, new[] { expectedOption }, overview, Example: null); + return new RoslynStyleRuleGroup([styleRule], [expectedOption], overview, Example: null); } public static RoslynQualityRule CA1064()