SharpSource 1.31.0
See the version list below for details.
dotnet add package SharpSource --version 1.31.0
NuGet\Install-Package SharpSource -Version 1.31.0
<PackageReference Include="SharpSource" Version="1.31.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="SharpSource" Version="1.31.0" />
<PackageReference Include="SharpSource"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add SharpSource --version 1.31.0
#r "nuget: SharpSource, 1.31.0"
#:package SharpSource@1.31.0
#addin nuget:?package=SharpSource&version=1.31.0
#tool nuget:?package=SharpSource&version=1.31.0

Quickstart
Install it through the command line:
Install-Package SharpSource
or add a reference yourself:
<ItemGroup>
<PackageReference Include="SharpSource" Version="1.31.0" PrivateAssets="All" />
</ItemGroup>
If you would like to install it as an extension instead, download it from the marketplace.
This repo houses a collection of analyzers that aim to make some language features and framework types easier to work with. It does this by highlighting when you might be using something incorrectly in a way that would result in suboptimal performance, runtime exceptions or general unintended behaviour.
In other words, this repo only contains analyzers for patterns that have a concrete potential to turn into a defect ticket. It is not intended to help with general housekeeping tasks like formatting your code or providing productivity helpers.
Interested in contributing? Take a look at the guidelines!
Detailed explanations of each analyzer can be found in the documentation: https://github.com/Vannevelj/SharpSource/tree/master/docs
| Code | Name | Description |
|---|---|---|
| SS001 | AsyncMethodWithVoidReturnType | Async methods should return Task instead of void to allow proper exception handling and awaiting. |
| SS002 | DateTimeNow | Use DateTime.UtcNow instead of DateTime.Now to avoid timezone-related issues. |
| SS003 | DivideIntegerByInteger | Dividing integers results in integer division; cast to floating-point if a decimal result is expected. |
| SS004 | ElementaryMethodsOfTypeInCollectionNotOverridden | Types used as collection keys should override Equals and GetHashCode. |
| SS005 | EqualsAndGetHashcodeNotImplementedTogether | Equals and GetHashCode should always be overridden together. |
| SS006 | ThrowNull | Throwing null will result in a NullReferenceException at runtime. |
| SS007 | FlagsEnumValuesAreNotPowersOfTwo | Flags enum values should be powers of two to allow proper bitwise operations. |
| SS008 | GetHashCodeRefersToMutableMember | GetHashCode should not reference mutable members as this breaks hash-based collections. |
| SS009 | LoopedRandomInstantiation | Creating Random instances in a loop can produce identical sequences; reuse a single instance. |
| SS010 | NewGuid | Use Guid.NewGuid() instead of new Guid() to generate a unique identifier. |
| SS011 | OnPropertyChangedWithoutNameofOperator | Use nameof() instead of hardcoded property name strings in OnPropertyChanged. |
| SS012 | RecursiveOperatorOverload | Operator overloads calling themselves will cause infinite recursion. |
| SS013 | RethrowExceptionWithoutLosingStacktrace | Use throw; instead of throw ex; to preserve the original stack trace. |
| SS014 | StringDotFormatWithDifferentAmountOfArguments | The number of format placeholders should match the number of arguments. |
| SS015 | StringPlaceholdersInWrongOrder | Format placeholders should be in sequential order starting from {0}. |
| SS017 | StructWithoutElementaryMethodsOverridden | Structs should override Equals, GetHashCode, and implement IEquatable<T> for performance. |
| SS018 | SwitchDoesNotHandleAllEnumOptions | Switch statements on enums should handle all possible values. |
| SS019 | SwitchIsMissingDefaultLabel | Switch statements should have a default case to handle unexpected values. |
| SS020 | TestMethodWithoutPublicModifier | Test methods must be public to be discovered by test runners. |
| SS021 | TestMethodWithoutTestAttribute | Methods that look like tests should have a test attribute to be executed. |
| SS022 | ExceptionThrownFromImplicitOperator | Implicit operators should not throw exceptions as they are called invisibly. |
| SS023 | ExceptionThrownFromPropertyGetter | Property getters should not throw exceptions; consider using a method instead. |
| SS024 | ExceptionThrownFromStaticConstructor | Exceptions in static constructors cause TypeInitializationException and make the type unusable. |
| SS025 | ExceptionThrownFromFinallyBlock | Exceptions in finally blocks can mask original exceptions from try blocks. |
| SS026 | ExceptionThrownFromEqualityOperator | Equality operators should not throw exceptions; return false for invalid comparisons. |
| SS027 | ExceptionThrownFromDispose | Dispose methods should not throw exceptions as they may be called during exception unwinding. |
| SS028 | ExceptionThrownFromFinalizer | Finalizers should not throw exceptions as this will terminate the process. |
| SS029 | ExceptionThrownFromGetHashCode | GetHashCode should not throw exceptions; return a consistent value instead. |
| SS030 | ExceptionThrownFromEquals | Equals should not throw exceptions; return false for invalid comparisons. |
| SS032 | ThreadSleepInAsyncMethod | Use await Task.Delay() instead of Thread.Sleep() in async methods to avoid blocking threads. |
| SS033 | AsyncOverloadsAvailable | Use async overloads when available to avoid blocking the calling thread. |
| SS034 | AccessingTaskResultWithoutAwait | Accessing Task.Result without awaiting can cause deadlocks; use await instead. |
| SS035 | SynchronousTaskWait | Using .Wait() or .Result on tasks can cause deadlocks; use await instead. |
| SS036 | ExplicitEnumValues | Enum members should have explicit values when the values are persisted or serialized. |
| SS037 | HttpClientInstantiatedDirectly | Use IHttpClientFactory instead of creating HttpClient directly to avoid socket exhaustion. |
| SS038 | HttpContextStoredInField | HttpContext should not be stored in fields as it's request-scoped and may be invalid later. |
| SS039 | EnumWithoutDefaultValue | Enums should have a member with value 0 to represent the default state. |
| SS040 | UnusedResultOnImmutableObject | Methods on immutable types return new instances; the result should not be discarded. |
| SS041 | UnnecessaryEnumerableMaterialization | Avoid materializing enumerables (e.g., ToList()) when the result is immediately enumerated. |
| SS042 | InstanceFieldWithThreadStatic | [ThreadStatic] only works on static fields; it has no effect on instance fields. |
| SS043 | MultipleFromBodyParameters | Web API actions can only have one [FromBody] parameter. |
| SS044 | AttributeMustSpecifyAttributeUsage | Custom attributes should specify [AttributeUsage] to define valid targets. |
| SS045 | StaticInitializerAccessedBeforeInitialization | Static field initializers may access fields before they are initialized. |
| SS046 | UnboundedStackalloc | stackalloc without a size limit can cause stack overflow; consider using a maximum size. |
| SS047 | LinqTraversalBeforeFilter | Apply Where filters before Select projections to avoid unnecessary work. |
| SS048 | LockingOnDiscouragedObject | Avoid locking on this, typeof(), or strings as these can cause deadlocks. |
| SS049 | ComparingStringsWithoutStringComparison | String comparisons should specify a StringComparison to ensure correct behavior. |
| SS050 | ParameterAssignedInConstructor | Assigning to a parameter instead of a field in a constructor is likely a mistake. |
| SS051 | LockingOnMutableReference | Locking on a field that can be reassigned may cause race conditions. |
| SS052 | ThreadStaticWithInitializer | [ThreadStatic] field initializers only run once; use lazy initialization instead. |
| SS053 | PointlessCollectionToString | Calling ToString() on collections returns the type name, not the contents. |
| SS054 | NewtonsoftMixedWithSystemTextJson | Mixing Newtonsoft.Json and System.Text.Json attributes causes serialization issues. |
| SS055 | MultipleOrderByCalls | Multiple OrderBy calls override each other; use ThenBy for secondary sorting. |
| SS056 | FormReadSynchronously | Reading form data synchronously blocks threads; use async methods instead. |
| SS057 | CollectionManipulatedDuringTraversal | Modifying a collection while iterating over it causes InvalidOperationException. |
| SS058 | StringConcatenatedInLoop | Use StringBuilder instead of string concatenation in loops for better performance. |
| SS059 | DisposeAsyncDisposable | Types implementing IAsyncDisposable should be disposed with await using. |
| SS060 | ConcurrentDictionaryEmptyCheck | Use IsEmpty instead of Count == 0 on ConcurrentDictionary for thread safety. |
| SS061 | ImmutableCollectionCreatedIncorrectly | Use builder methods or Create() instead of constructors for immutable collections. |
| SS062 | ActivityWasNotStopped | Activity instances must be stopped to ensure telemetry data is recorded. |
| SS063 | ValueTaskAwaitedMultipleTimes | ValueTask can only be awaited once; store the result or convert to Task if needed. |
| SS064 | UnnecessaryToStringOnSpan | Avoid calling ToString() on spans when an overload accepting spans directly is available. |
| SS065 | LoggerMessageAttribute | Use the [LoggerMessage] attribute for high-performance logging instead of extension methods. |
Configuration
Is a particular rule not to your liking? There are many ways to adjust their severity and even disable them altogether. For an overview of some of the options, check out this document.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.31.1 | 0 | 1/25/2026 |
| 1.31.0 | 40 | 1/24/2026 |
| 1.30.0 | 57 | 1/23/2026 |
| 1.29.0 | 75 | 1/22/2026 |
| 1.28.0 | 189 | 1/21/2026 |
| 1.27.1 | 19,643 | 2/22/2025 |
| 1.27.0 | 1,528 | 1/10/2025 |
| 1.26.0 | 542 | 12/19/2024 |
| 1.25.2 | 15,691 | 9/15/2024 |
| 1.25.1 | 237 | 9/15/2024 |
| 1.25.0 | 239 | 9/15/2024 |
| 1.24.1 | 273 | 9/13/2024 |
| 1.24.0 | 24,678 | 2/21/2024 |
| 1.23.4 | 998 | 1/5/2024 |
| 1.23.3 | 6,489 | 5/15/2023 |
| 1.23.2 | 906 | 3/18/2023 |
| 1.23.1 | 2,162 | 2/28/2023 |
| 1.23.0 | 461 | 2/26/2023 |
| 1.22.2 | 402 | 2/25/2023 |
| 1.22.1 | 433 | 2/21/2023 |
| 1.22.0 | 425 | 2/21/2023 |
| 1.21.6 | 838 | 2/10/2023 |
| 1.21.5 | 534 | 1/31/2023 |
| 1.21.4 | 490 | 1/29/2023 |
| 1.21.3 | 482 | 1/25/2023 |
| 1.21.2 | 475 | 1/23/2023 |
| 1.21.1 | 452 | 1/22/2023 |
| 1.21.0 | 471 | 1/21/2023 |
| 1.20.0 | 492 | 1/20/2023 |
| 1.19.1 | 527 | 1/14/2023 |
| 1.19.0 | 485 | 1/12/2023 |
| 1.18.0 | 11,112 | 1/10/2023 |
| 1.17.6 | 497 | 1/8/2023 |
| 1.17.5 | 519 | 1/6/2023 |
| 1.17.4 | 482 | 1/4/2023 |
| 1.17.3 | 469 | 1/3/2023 |
| 1.17.2 | 494 | 1/2/2023 |
| 1.17.1 | 454 | 1/2/2023 |
| 1.17.0 | 501 | 1/1/2023 |
| 1.16.22 | 501 | 1/1/2023 |
| 1.16.21 | 504 | 1/1/2023 |
| 1.16.20 | 491 | 1/1/2023 |
| 1.16.19 | 484 | 1/1/2023 |
| 1.16.18 | 464 | 12/31/2022 |
| 1.16.17 | 453 | 12/31/2022 |
| 1.16.16 | 471 | 12/30/2022 |
| 1.16.15 | 495 | 12/30/2022 |
| 1.16.14 | 502 | 12/30/2022 |
| 1.16.13 | 451 | 12/30/2022 |
| 1.16.12 | 480 | 12/30/2022 |
| 1.16.11 | 461 | 12/30/2022 |
| 1.16.10 | 453 | 12/30/2022 |
| 1.16.9 | 488 | 12/30/2022 |
| 1.16.8 | 450 | 12/30/2022 |
| 1.16.7 | 483 | 12/30/2022 |
| 1.16.6 | 468 | 12/30/2022 |
| 1.16.5 | 511 | 12/29/2022 |
| 1.16.4 | 477 | 12/29/2022 |
| 1.16.3 | 470 | 12/29/2022 |
| 1.16.2 | 492 | 12/29/2022 |
| 1.16.1 | 485 | 12/28/2022 |
| 1.16.0 | 459 | 12/27/2022 |
| 1.15.0 | 488 | 12/25/2022 |
| 1.14.1 | 9,823 | 10/16/2022 |
| 1.14.0 | 611 | 10/16/2022 |
| 1.13.1 | 590 | 10/1/2022 |
| 1.13.0 | 589 | 10/1/2022 |
| 1.12.0 | 617 | 9/25/2022 |
| 1.11.2 | 588 | 9/25/2022 |
| 1.11.1 | 586 | 9/24/2022 |
| 1.11.0 | 628 | 9/24/2022 |
| 1.10.1 | 607 | 9/16/2022 |
| 1.10.0 | 661 | 9/14/2022 |
| 1.9.4 | 669 | 9/13/2022 |
| 1.9.3 | 595 | 9/12/2022 |
| 1.9.2 | 580 | 9/12/2022 |
| 1.9.1 | 607 | 9/11/2022 |
| 1.9.0 | 615 | 9/11/2022 |
| 1.8.0 | 588 | 9/8/2022 |
| 1.7.2 | 595 | 9/6/2022 |
| 1.7.1 | 623 | 9/5/2022 |
| 1.7.0 | 619 | 9/5/2022 |
| 1.6.0 | 548 | 9/4/2022 |
| 1.5.0 | 551 | 9/4/2022 |
| 1.4.2 | 590 | 9/4/2022 |
| 1.3.1 | 587 | 9/3/2022 |
| 1.3.0 | 616 | 9/2/2022 |
| 1.2.4 | 592 | 8/31/2022 |
| 1.2.3 | 627 | 8/29/2022 |
| 1.2.2 | 593 | 8/29/2022 |
| 1.2.1 | 599 | 8/29/2022 |
| 1.2.0 | 619 | 8/29/2022 |
| 1.1.1 | 603 | 8/28/2022 |
| 1.1.0 | 603 | 8/28/2022 |
| 1.0.0 | 606 | 8/28/2022 |
| 0.9.0 | 626 | 8/26/2022 |
| 0.8.0 | 586 | 8/23/2022 |
| 0.7.0 | 580 | 8/22/2022 |
| 0.6.0 | 626 | 8/15/2022 |
| 0.5.0 | 581 | 8/14/2022 |
| 0.4.0 | 621 | 8/14/2022 |
| 0.3.0 | 734 | 5/10/2020 |
| 0.2.0 | 735 | 4/12/2020 |
| 0.1.0 | 850 | 4/12/2020 |
For a full overview of the changes, visit https://github.com/vannevelj/sharpsource/releases