A Roslyn analyzer to enforce some good practices in C# in terms of design, usage, security, performance, and style.
Install the NuGet package https://www.nuget.org/packages/Meziantou.Analyzer/
If you are already using other analyzers, you can check which rules are duplicated with well-known analyzers
Id | Category | Description | Severity | Is enabled | Code fix |
---|---|---|---|---|---|
MA0001 | Usage | StringComparison is missing | ℹ️ | ✔️ | ✔️ |
MA0002 | Usage | IEqualityComparer\<string> or IComparer\<string> is missing | ⚠️ | ✔️ | ✔️ |
MA0003 | Style | Add parameter name to improve readability | ℹ️ | ✔️ | ✔️ |
MA0004 | Usage | Use Task.ConfigureAwait | ⚠️ | ✔️ | ✔️ |
MA0005 | Performance | Use Array.Empty\<T>() | ⚠️ | ✔️ | ✔️ |
MA0006 | Usage | Use String.Equals instead of equality operator | ⚠️ | ✔️ | ✔️ |
MA0007 | Style | Add a comma after the last value | ℹ️ | ✔️ | ✔️ |
MA0008 | Performance | Add StructLayoutAttribute | ⚠️ | ✔️ | ✔️ |
MA0009 | Security | Add regex evaluation timeout | ⚠️ | ✔️ | ❌ |
MA0010 | Design | Mark attributes with AttributeUsageAttribute | ⚠️ | ✔️ | ✔️ |
MA0011 | Usage | IFormatProvider is missing | ⚠️ | ✔️ | ❌ |
MA0012 | Design | Do not raise reserved exception type | ⚠️ | ✔️ | ❌ |
MA0013 | Design | Types should not extend System.ApplicationException | ⚠️ | ✔️ | ❌ |
MA0014 | Design | Do not raise System.ApplicationException type | ⚠️ | ✔️ | ❌ |
MA0015 | Usage | Specify the parameter name in ArgumentException | ⚠️ | ✔️ | ❌ |
MA0016 | Design | Prefer using collection abstraction instead of implementation | ⚠️ | ✔️ | ❌ |
MA0017 | Design | Abstract types should not have public or internal constructors | ⚠️ | ✔️ | ✔️ |
MA0018 | Design | Do not declare static members on generic types (deprecated; use CA1000 instead) | ℹ️ | ✔️ | ❌ |
MA0019 | Usage | Use EventArgs.Empty | ⚠️ | ✔️ | ✔️ |
MA0020 | Performance | Use direct methods instead of LINQ methods | ℹ️ | ✔️ | ✔️ |
MA0021 | Usage | Use StringComparer.GetHashCode instead of string.GetHashCode | ⚠️ | ✔️ | ✔️ |
MA0022 | Design | Return Task.FromResult instead of returning null | ⚠️ | ✔️ | ✔️ |
MA0023 | Performance | Add RegexOptions.ExplicitCapture | ⚠️ | ✔️ | ❌ |
MA0024 | Usage | Use an explicit StringComparer when possible | ⚠️ | ✔️ | ✔️ |
MA0025 | Design | Implement the functionality instead of throwing NotImplementedException | ⚠️ | ✔️ | ❌ |
MA0026 | Design | Fix TODO comment | ⚠️ | ✔️ | ❌ |
MA0027 | Usage | Prefer rethrowing an exception implicitly | ⚠️ | ✔️ | ✔️ |
MA0028 | Performance | Optimize StringBuilder usage | ℹ️ | ✔️ | ✔️ |
MA0029 | Performance | Combine LINQ methods | ℹ️ | ✔️ | ✔️ |
MA0030 | Performance | Remove useless OrderBy call | ⚠️ | ✔️ | ✔️ |
MA0031 | Performance | Optimize Enumerable.Count() usage | ℹ️ | ✔️ | ✔️ |
MA0032 | Usage | Use an overload with a CancellationToken argument | ℹ️ | ❌ | ❌ |
MA0033 | Design | Do not tag instance fields with ThreadStaticAttribute | ⚠️ | ✔️ | ❌ |
MA0035 | Usage | Do not use dangerous threading methods | ⚠️ | ✔️ | ❌ |
MA0036 | Design | Make class static | ℹ️ | ✔️ | ✔️ |
MA0037 | Usage | Remove empty statement | ❌ | ✔️ | ✔️ |
MA0038 | Design | Make method static (deprecated, use CA1822 instead) | ℹ️ | ✔️ | ✔️ |
MA0039 | Security | Do not write your own certificate validation method | ❌ | ✔️ | ❌ |
MA0040 | Usage | Forward the CancellationToken parameter to methods that take one | ℹ️ | ✔️ | ✔️ |
MA0041 | Design | Make property static (deprecated, use CA1822 instead) | ℹ️ | ✔️ | ✔️ |
MA0042 | Design | Do not use blocking calls in an async method | ℹ️ | ✔️ | ✔️ |
MA0043 | Usage | Use nameof operator in ArgumentException | ℹ️ | ✔️ | ✔️ |
MA0044 | Performance | Remove useless ToString call | ℹ️ | ✔️ | ✔️ |
MA0045 | Design | Do not use blocking calls in a sync method (need to make calling method async) | ℹ️ | ❌ | ✔️ |
MA0046 | Design | Use EventHandler\<T> to declare events | ⚠️ | ✔️ | ❌ |
MA0047 | Design | Declare types in namespaces | ⚠️ | ✔️ | ❌ |
MA0048 | Design | File name must match type name | ⚠️ | ✔️ | ❌ |
MA0049 | Design | Type name should not match containing namespace | ❌ | ✔️ | ❌ |
MA0050 | Design | Validate arguments correctly in iterator methods | ℹ️ | ✔️ | ✔️ |
MA0051 | Design | Method is too long | ⚠️ | ✔️ | ❌ |
MA0052 | Performance | Replace constant Enum.ToString with nameof | ℹ️ | ✔️ | ✔️ |
MA0053 | Design | Make class sealed | ℹ️ | ✔️ | ✔️ |
MA0054 | Design | Embed the caught exception as innerException | ⚠️ | ✔️ | ❌ |
MA0055 | Design | Do not use finalizer | ⚠️ | ✔️ | ❌ |
MA0056 | Design | Do not call overridable members in constructor | ⚠️ | ✔️ | ❌ |
MA0057 | Naming | Class name should end with 'Attribute' | ℹ️ | ✔️ | ❌ |
MA0058 | Naming | Class name should end with 'Exception' | ℹ️ | ✔️ | ❌ |
MA0059 | Naming | Class name should end with 'EventArgs' | ℹ️ | ✔️ | ❌ |
MA0060 | Design | The value returned by Stream.Read/Stream.ReadAsync is not used | ⚠️ | ✔️ | ❌ |
MA0061 | Design | Method overrides should not change default values | ⚠️ | ✔️ | ✔️ |
MA0062 | Design | Non-flags enums should not be marked with "FlagsAttribute" | ⚠️ | ✔️ | ❌ |
MA0063 | Performance | Use Where before OrderBy | ℹ️ | ✔️ | ❌ |
MA0064 | Design | Avoid locking on publicly accessible instance | ⚠️ | ✔️ | ❌ |
MA0065 | Performance | Default ValueType.Equals or HashCode is used for struct equality | ⚠️ | ✔️ | ❌ |
MA0066 | Performance | Hash table unfriendly type is used in a hash table | ⚠️ | ✔️ | ❌ |
MA0067 | Design | Use Guid.Empty | ℹ️ | ✔️ | ✔️ |
MA0068 | Design | Invalid parameter name for nullable attribute | ⚠️ | ✔️ | ❌ |
MA0069 | Design | Non-constant static fields should not be visible | ⚠️ | ✔️ | ❌ |
MA0070 | Design | Obsolete attributes should include explanations | ⚠️ | ✔️ | ❌ |
MA0071 | Style | Avoid using redundant else | ℹ️ | ✔️ | ✔️ |
MA0072 | Design | Do not throw from a finally block | ⚠️ | ✔️ | ❌ |
MA0073 | Style | Avoid comparison with bool constant | ℹ️ | ✔️ | ✔️ |
MA0074 | Usage | Avoid implicit culture-sensitive methods | ⚠️ | ✔️ | ✔️ |
MA0075 | Design | Do not use implicit culture-sensitive ToString | ℹ️ | ✔️ | ❌ |
MA0076 | Design | Do not use implicit culture-sensitive ToString in interpolated strings | ℹ️ | ✔️ | ❌ |
MA0077 | Design | A class that provides Equals(T) should implement IEquatable\<T> | ⚠️ | ✔️ | ✔️ |
MA0078 | Performance | Use 'Cast' instead of 'Select' to cast | ℹ️ | ✔️ | ✔️ |
MA0079 | Usage | Forward the CancellationToken using .WithCancellation() | ℹ️ | ✔️ | ✔️ |
MA0080 | Usage | Use a cancellation token using .WithCancellation() | ℹ️ | ❌ | ❌ |
MA0081 | Design | Method overrides should not omit params keyword | ⚠️ | ✔️ | ✔️ |
MA0082 | Design | NaN should not be used in comparisons | ⚠️ | ✔️ | ❌ |
MA0083 | Design | ConstructorArgument parameters should exist in constructors | ⚠️ | ✔️ | ❌ |
MA0084 | Design | Local variables should not hide other symbols | ⚠️ | ✔️ | ❌ |
MA0085 | Usage | Anonymous delegates should not be used to unsubscribe from Events | ⚠️ | ✔️ | ❌ |
MA0086 | Design | Do not throw from a finalizer | ⚠️ | ✔️ | ❌ |
MA0087 | Design | Parameters with [DefaultParameterValue] attributes should also be marked [Optional] | ⚠️ | ✔️ | ❌ |
MA0088 | Design | Use [DefaultParameterValue] instead of [DefaultValue] | ⚠️ | ✔️ | ❌ |
MA0089 | Performance | Optimize string method usage | ℹ️ | ✔️ | ✔️ |
MA0090 | Design | Remove empty else/finally block | ℹ️ | ✔️ | ❌ |
MA0091 | Usage | Sender should be 'this' for instance events | ⚠️ | ✔️ | ✔️ |
MA0092 | Usage | Sender should be 'null' for static events | ⚠️ | ✔️ | ❌ |
MA0093 | Usage | EventArgs should not be null | ⚠️ | ✔️ | ✔️ |
MA0094 | Design | A class that provides CompareTo(T) should implement IComparable\<T> | ⚠️ | ✔️ | ❌ |
MA0095 | Design | A class that implements IEquatable\<T> should override Equals(object) | ⚠️ | ✔️ | ❌ |
MA0096 | Design | A class that implements IComparable\<T> should also implement IEquatable\<T> | ⚠️ | ✔️ | ❌ |
MA0097 | Design | A class that implements IComparable\<T> or IComparable should override comparison operators | ⚠️ | ✔️ | ❌ |
MA0098 | Performance | Use indexer instead of LINQ methods | ℹ️ | ✔️ | ✔️ |
MA0099 | Usage | Use Explicit enum value instead of 0 | ⚠️ | ✔️ | ❌ |
MA0100 | Usage | Await task before disposing of resources | ⚠️ | ✔️ | ❌ |
MA0101 | Usage | String contains an implicit end of line character | 👻 | ✔️ | ✔️ |
MA0102 | Design | Make member readonly | ℹ️ | ✔️ | ✔️ |
MA0103 | Usage | Use SequenceEqual instead of equality operator | ⚠️ | ✔️ | ✔️ |
MA0104 | Design | Do not create a type with a name from the BCL | ⚠️ | ❌ | ❌ |
MA0105 | Performance | Use the lambda parameters instead of using a closure | ℹ️ | ✔️ | ❌ |
MA0106 | Performance | Avoid closure by using an overload with the 'factoryArgument' parameter | ℹ️ | ✔️ | ❌ |
MA0107 | Design | Do not use culture-sensitive object.ToString | ℹ️ | ❌ | ❌ |
MA0108 | Usage | Remove redundant argument value | ℹ️ | ✔️ | ✔️ |
MA0109 | Design | Consider adding an overload with a Span\<T> or Memory\<T> | ℹ️ | ❌ | ❌ |
MA0110 | Performance | Use the Regex source generator | ℹ️ | ✔️ | ✔️ |
MA0111 | Performance | Use string.Create instead of FormattableString | ℹ️ | ✔️ | ✔️ |
MA0112 | Performance | Use 'Count > 0' instead of 'Any()' | ℹ️ | ❌ | ❌ |
MA0113 | Design | Use DateTime.UnixEpoch | ℹ️ | ✔️ | ✔️ |
MA0114 | Design | Use DateTimeOffset.UnixEpoch | ℹ️ | ✔️ | ✔️ |
MA0115 | Usage | Unknown component parameter | ⚠️ | ✔️ | ❌ |
MA0116 | Design | Parameters with [SupplyParameterFromQuery] attributes should also be marked as [Parameter] | ⚠️ | ✔️ | ✔️ |
MA0117 | Design | Parameters with [EditorRequired] attributes should also be marked as [Parameter] | ⚠️ | ✔️ | ✔️ |
MA0118 | Design | [JSInvokable] methods must be public | ⚠️ | ✔️ | ❌ |
MA0119 | Design | JSRuntime must not be used in OnInitialized or OnInitializedAsync | ⚠️ | ✔️ | ❌ |
MA0120 | Performance | Use InvokeVoidAsync when the returned value is not used | ℹ️ | ✔️ | ✔️ |
MA0121 | Design | Do not overwrite parameter value | ℹ️ | ❌ | ❌ |
MA0122 | Design | Parameters with [SupplyParameterFromQuery] attributes are only valid in routable components (@page) | ℹ️ | ✔️ | ❌ |
MA0123 | Design | Sequence number must be a constant | ⚠️ | ✔️ | ❌ |
MA0124 | Design | Log parameter type is not valid | ⚠️ | ✔️ | ❌ |
MA0125 | Design | The list of log parameter types contains an invalid type | ⚠️ | ✔️ | ❌ |
MA0126 | Design | The list of log parameter types contains a duplicate | ⚠️ | ✔️ | ❌ |
MA0127 | Usage | Use String.Equals instead of is pattern | ⚠️ | ❌ | ❌ |
MA0128 | Usage | Use 'is' operator instead of SequenceEqual | ℹ️ | ✔️ | ✔️ |
MA0129 | Usage | Await task in using statement | ⚠️ | ✔️ | ❌ |
MA0130 | Usage | GetType() should not be used on System.Type instances | ⚠️ | ✔️ | ❌ |
MA0131 | Usage | ArgumentNullException.ThrowIfNull should not be used with non-nullable types | ⚠️ | ✔️ | ❌ |
MA0132 | Design | Do not convert implicitly to DateTimeOffset | ⚠️ | ✔️ | ❌ |
MA0133 | Design | Use DateTimeOffset instead of relying on the implicit conversion | ℹ️ | ✔️ | ❌ |
MA0134 | Usage | Observe result of async calls | ⚠️ | ✔️ | ❌ |
MA0135 | Design | The log parameter has no configured type | ⚠️ | ❌ | ❌ |
MA0136 | Usage | Raw String contains an implicit end of line character | 👻 | ✔️ | ❌ |
MA0137 | Design | Use 'Async' suffix when a method returns an awaitable type | ⚠️ | ❌ | ❌ |
MA0138 | Design | Do not use 'Async' suffix when a method does not return an awaitable type | ⚠️ | ❌ | ❌ |
MA0139 | Design | Log parameter type is not valid | ⚠️ | ✔️ | ❌ |
MA0140 | Design | Both if and else branch have identical code | ⚠️ | ✔️ | ❌ |
MA0141 | Usage | Use pattern matching instead of inequality operators for null check | ℹ️ | ❌ | ✔️ |
MA0142 | Usage | Use pattern matching instead of equality operators for null check | ℹ️ | ❌ | ✔️ |
MA0143 | Design | Primary constructor parameters should be readonly | ⚠️ | ✔️ | ❌ |
MA0144 | Performance | Use System.OperatingSystem to check the current OS | ⚠️ | ✔️ | ❌ |
MA0145 | Usage | Signature for [UnsafeAccessorAttribute] method is not valid | ⚠️ | ✔️ | ❌ |
MA0146 | Usage | Name must be set explicitly on local functions | ⚠️ | ✔️ | ❌ |
MA0147 | Usage | Avoid async void method for delegate | ⚠️ | ✔️ | ❌ |
MA0148 | Usage | Use pattern matching instead of equality operators for discrete value | ℹ️ | ❌ | ✔️ |
MA0149 | Usage | Use pattern matching instead of inequality operators for discrete value | ℹ️ | ❌ | ✔️ |
MA0150 | Design | Do not call the default object.ToString explicitly | ⚠️ | ✔️ | ❌ |
MA0151 | Usage | DebuggerDisplay must contain valid members | ⚠️ | ✔️ | ❌ |
MA0152 | Performance | Use Unwrap instead of using await twice | ℹ️ | ✔️ | ❌ |
MA0153 | Design | Do not log symbols decorated with DataClassificationAttribute directly | ⚠️ | ✔️ | ❌ |
MA0154 | Design | Use langword in XML comment | ℹ️ | ✔️ | ✔️ |
MA0155 | Design | Do not use async void methods | ⚠️ | ❌ | ❌ |
MA0156 | Design | Use 'Async' suffix when a method returns IAsyncEnumerable\<T> | ⚠️ | ❌ | ❌ |
MA0157 | Design | Do not use 'Async' suffix when a method does not return IAsyncEnumerable\<T> | ⚠️ | ❌ | ❌ |
MA0158 | Performance | Use System.Threading.Lock | ⚠️ | ✔️ | ❌ |
MA0159 | Performance | Use 'Order' instead of 'OrderBy' | ℹ️ | ✔️ | ✔️ |
MA0160 | Performance | Use ContainsKey instead of TryGetValue | ℹ️ | ✔️ | ❌ |
MA0161 | Usage | UseShellExecute must be explicitly set | ℹ️ | ❌ | ❌ |
MA0162 | Usage | Use Process.Start overload with ProcessStartInfo | ℹ️ | ❌ | ❌ |
MA0163 | Usage | UseShellExecute must be false when redirecting standard input or output | ⚠️ | ✔️ | ❌ |
MA0164 | Style | Use parentheses to make not pattern clearer | ⚠️ | ✔️ | ✔️ |
MA0165 | Usage | Make interpolated string | 👻 | ✔️ | ✔️ |
Id | Suppressed rule | Justification |
---|---|---|
MAS0001 |
CA1822 | Suppress CA1822 on methods decorated with BenchmarkDotNet attributes. |
MAS0002 |
CA1822 | Suppress CA1822 on methods decorated with a System.Text.Json attribute such as [JsonPropertyName] or [JsonInclude]. |
MAS0003 |
IDE0058 | Suppress IDE0058 on well-known types |