From 071f93aafecd0794689c8a891f773d13e7aaed74 Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:18:16 +0200 Subject: [PATCH] Modify rule S2997: LaYC format (#2353) --- rules/S2997/metadata.json | 2 +- rules/S2997/rule.adoc | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/rules/S2997/metadata.json b/rules/S2997/metadata.json index 5aa2dbdf7f..bdb71e6db2 100644 --- a/rules/S2997/metadata.json +++ b/rules/S2997/metadata.json @@ -24,5 +24,5 @@ "defaultQualityProfiles": [ "Sonar way" ], - "quickfix": "unknown" + "quickfix": "infeasible" } diff --git a/rules/S2997/rule.adoc b/rules/S2997/rule.adoc index a5db229092..2b49caf485 100644 --- a/rules/S2997/rule.adoc +++ b/rules/S2997/rule.adoc @@ -1,34 +1,45 @@ == Why is this an issue? -Typically you want to use ``++using++`` to create a local ``++IDisposable++`` variable; it will trigger disposal of the object when control passes out of the block's scope. The exception to this rule is when your method returns that ``++IDisposable++``. In that case ``++using++`` disposes of the object before the caller can make use of it, likely causing exceptions at runtime. So you should either remove ``++using++`` or avoid returning the ``++IDisposable++``. +When you use a https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using[`using` statement], the goal is to ensure the correct disposal of an https://learn.microsoft.com/en-us/dotnet/api/system.idisposable[`IDisposable`] instance when the control leaves the `using` statement block. +If you return that `IDisposable` instance inside the block, `using` will dispose it before the caller can use it, likely causing exceptions at runtime. You should either remove `using` statement or avoid returning the `IDisposable` in the `using` statement block. -=== Noncompliant code example +== How to fix it -[source,text] +=== Code examples + +==== Noncompliant code example + +[source,csharp,diff-id=1,diff-type=noncompliant] ---- public FileStream WriteToFile(string path, string text) { - using (var fs = File.Create(path)) // Noncompliant + using (var fs = File.Create(path)) // Noncompliant: 'fs' is disposed at the end of the using scope { var bytes = Encoding.UTF8.GetBytes(text); fs.Write(bytes, 0, bytes.Length); - return fs; + return fs; } } ---- -=== Compliant solution +==== Compliant solution -[source,text] +[source,csharp,diff-id=1,diff-type=compliant] ---- public FileStream WriteToFile(string path, string text) { var fs = File.Create(path); var bytes = Encoding.UTF8.GetBytes(text); fs.Write(bytes, 0, bytes.Length); - return fs; + return fs; // Compliant: 'fs' is not disposed once the end of the scope is reached and the caller can use it } ---- +== Resources + +=== Documentation + +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using[using statement - ensure the correct use of disposable objects] +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.idisposable[IDisposable]