Skip to content

green-code-initiative/ecoCode-csharp

Repository files navigation

EcoCode on NuGet EcoCode on NuGet

EcoCode-C#

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.

License: GPL v3 Contributor Covenant

🚀 Getting Started

There are several ways you can use the ecoCode C# analyzers in your .Net projects:

  1. As a NuGet package
  2. As a .NET tool
  3. As an analyzer for SonarQube.

🧩 NuGet package

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.

🧩 .Net tool

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.

🧩 Analyzer for SonarQube

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.

🌿 EcoCode Rules

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 ℹ️ ✔️

🌿 Customized Roslyn Rules

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' ℹ️ ⚠️

🤝 Contribution

See contribution on the central ecoCode repository.

🤓 Main contributors

See main contributors on the central ecoCode repository.