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 | ❌ | ❌ |
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]. |