ecoCode is a collective project aiming to reduce environmental footprint of software at the code level. The goal of the project is to provide a list of static code analyzers to highlight code structures that may have a negative ecological impact: energy and resources over-consumption, "fatware", shortening terminals' lifespan, etc.
ecoCode is based on evolving catalogs of good practices, for various technologies. This set of Roslyn analyzers implements these catalogs as rules for scanning your C# projects.
There are several ways you can use the ecoCode C# analyzers in your .Net projects:
- As a NuGet package
- As a .NET tool
- As an analyzer for SonarQube.
The package is available on nuget.org at this address : https://www.nuget.org/packages/EcoCode, and can be added to your projects/solutions like any NuGet package. Once referenced and restored, the ecoCode analyzers are automatically integrated in your IDE/compilation process, and will list any applicable info/alert.
Pre-requisite : .Net Standard 2.0, which can be used in a wide range of projects. See Microsoft documentation for details about the supported Frameworks.
The .Net tool is available on nuget.org at this address : https://www.nuget.org/packages/EcoCode.Tool, and can be fetched on your machine using the following command :
dotnet tool install --global EcoCode.Tool
See .Net tools documentation for additional information.
Once installed, you can launch an analyzis on an existing codebase like this :
ecocode-cli analyze path/to/mySolution.sln path/to/myReport.html
.
The file to analyze can be a .sln, a .slnx or a .csproj. The report format depends on it's required extension, the following are currently supported : .html, .json and .csv.
Pre-requisite : .Net 8 SDK.
EcoCode C# can use SonarScanner for .Net to integrate with SonarQube, and uses a custom import addition to enrich what is reported to Sonar (severity, description, url page, category, and so on). See our dedicated repository for more information.
Id | Description | Severity | Code fix |
---|---|---|---|
EC69 | Don’t call loop invariant functions in loop conditions | ❌ | |
EC72 | Don’t execute SQL queries in loops | ❌ | |
EC75 | Don’t concatenate strings in loops |
❌ | |
EC81 | Specify struct layouts |
✔️ | |
EC82 | Variable can be made constant | ℹ️ | ✔️ |
EC83 | Replace Enum ToString() with nameof |
✔️ | |
EC84 | Avoid async void methods |
✔️ | |
EC85 | Make type sealed |
ℹ️ | ✔️ |
EC86 | GC.Collect should not be called |
❌ | |
EC87 | Use collection indexer | ✔️ | |
EC88 | Dispose resource asynchronously | ✔️ | |
EC91 | Use Where before OrderBy |
✔️ | |
EC92 | Use Length to test empty strings |
✔️ | |
EC93 | Return Task directly |
ℹ️ | ✔️ |
EcoCode C# customizes the severity of the following native Roslyn rules.
Id | Description | Old Severity | New Severity |
---|---|---|---|
CA1001 | Types that own disposable fields should be disposable | 💤 | |
CA1802 | Use Literals Where Appropriate | 💤 | |
CA1805 | Do not initialize unnecessarily | 💤 | |
CA1813 | Avoid unsealed attributes | 💤 | |
CA1816 | Call GC.SuppressFinalize correctly | ℹ️ | |
CA1821 | Remove empty finalizers | ℹ️ | |
CA1822 | Mark members as static | ℹ️ | |
CA1824 | Mark assemblies with NeutralResourcesLanguageAttribute | ℹ️ | |
CA1825 | Avoid zero-length array allocations | ℹ️ | |
CA1826 | Use property instead of Linq Enumerable method | ℹ️ | |
CA1827 | Do not use Count()/LongCount() when Any() can be used | ℹ️ | |
CA1828 | Do not use CountAsync/LongCountAsync when AnyAsync can be used | ℹ️ | |
CA1829 | Use Length/Count property instead of Enumerable.Count method | ℹ️ | |
CA1830 | Prefer strongly-typed Append and Insert method overloads on StringBuilder | ℹ️ | |
CA1832 | Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array | ℹ️ | |
CA1833 | Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array | ℹ️ | |
CA1834 | Use StringBuilder.Append(char) for single character strings | ℹ️ | |
CA1835 | Prefer the memory-based overloads of ReadAsync/WriteAsync methods in stream-based classes | ℹ️ | |
CA1836 | Prefer IsEmpty over Count when available | ℹ️ | |
CA1837 | Use Environment.ProcessId instead of Process.GetCurrentProcess().Id | ℹ️ | |
CA1838 | Avoid StringBuilder parameters for P/Invokes | 💤 | |
CA1839 | Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName | ℹ️ | |
CA1840 | Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId | ℹ️ | |
CA1841 | Prefer Dictionary Contains methods | ℹ️ | |
CA1842 | Do not use 'WhenAll' with a single task | ℹ️ | |
CA1843 | Do not use 'WaitAll' with a single task | ℹ️ | |
CA1844 | Provide memory-based overrides of async methods when subclassing 'Stream' | ℹ️ | |
CA1845 | Use span-based 'string.Concat' | ℹ️ | |
CA1846 | Prefer AsSpan over Substring | ℹ️ | |
CA1847 | Use String.Contains(char) instead of String.Contains(string) with single characters | ℹ️ | |
CA1850 | Prefer static HashData method over ComputeHash | ℹ️ | |
CA1853 | Unnecessary call to 'Dictionary.ContainsKey(key)' | ℹ️ | |
CA1854 | Prefer the IDictionary.TryGetValue(TKey, out TValue) method | ℹ️ | |
CA1855 | Use Span.Clear() instead of Span.Fill() | ℹ️ | |
CA1858 | Use StartsWith instead of IndexOf | ℹ️ | |
CA1859 | Prefer concrete types when possible for improved performance | ℹ️ | |
CA1860 | Avoid using 'Enumerable.Any()' extension method | ℹ️ | |
CA1863 | Use 'CompositeFormat' | 💤 | |
CA1864 | Prefer the 'IDictionary.TryAdd(TKey, TValue)' method | ℹ️ | |
CA1865-7 | Use 'string.Method(char)' instead of 'string.Method(string)' for string with single char | ℹ️ | |
CA1868 | Unnecessary call to 'Contains' for sets | ℹ️ | |
CA1869 | Cache and reuse 'JsonSerializerOptions' instances | ℹ️ | |
CA1870 | Use a cached 'SearchValues' instance | ℹ️ | |
CA1871 | Do not pass a nullable struct to 'ArgumentNullException.ThrowIfNull' | ℹ️ | |
CA1872 | Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString' | ℹ️ | |
CA2009 | Do not call ToImmutableCollection on an ImmutableCollection value | ℹ️ | |
CA2215 | Dispose methods should call base class dispose | 💤 | |
CA2218 | Override GetHashCode on overriding Equals | ℹ️ | |
CA2251 | Use String.Equals over String.Compare | 💤 | |
CA2264 | Do not pass a non-nullable value to 'ArgumentNullException.ThrowIfNull' | ℹ️ |
See contribution on the central ecoCode repository.
See main contributors on the central ecoCode repository.