Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- [#399](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/399) Add C# Rule GCI95 - Use `is` operator instead of `as` operator and null check
- GCI69 Java : calls to hasMoreElements() and nextElement() methods from java.util.Enumeration interface aren't flagged anymore when called in a for loop

- Correction of various typos in rules documentations
Expand Down
1 change: 1 addition & 0 deletions RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Some are applicable for different technologies.
| GCI92 | Use string.Length instead of comparison with empty string | Comparing a string to an empty string is unnecessary and can be replaced by a call to `string.Length` which is more performant and more readable. | | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ✅ | 🚫 |
| GCI93 | Return `Task` directly | Consider returning a `Task` directly instead of a single `await` | | ❓ | ❓ | ❓ | ❓ | ❓ | ✅ | ❓ |
| GCI94 | Use orElseGet instead of orElse | Parameter of orElse() is evaluated, even when having a non-empty Optional. Supplier method of orElseGet passed as an argument is only executed when an Optional value isn’t present. Therefore, using orElseGet() will save computing time. | [Optimized use of Java Optional Else](https://github.com/green-code-initiative/creedengo-challenge/issues/77) | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
| GCI95 | Use `x is string` instead of `x as string != null` | Using the `as` operator followed by a null check is more verbose and can be simplified using the `is` operator with pattern matching. When using the `is` pattern, the type check and cast happen in one concise statement, improving readability and reducing boilerplate. Therefore, using `is` with pattern matching will simplify code and improve maintainability. | [Roslynator Rule](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1172/) [Microsoft Documentation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast) | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ✅ | 🚫 |
| GCI203 | Detect unoptimized file formats | When it is possible, to use svg format image over other image format | | 🚧 | 🚀 | 🚀 | ✅ | 🚀 | 🚀 | 🚫 |
| GCI404 | Avoid list comprehension in iterations | Use generator comprehension instead of list comprehension in for loop declaration | | 🚫 | 🚫 | 🚫 | ✅ | 🚫 | 🚫 | 🚫 |
| GCI522 | Sobriety: Brightness Override | To avoid draining the battery, iOS and Android devices adapt the brightness of the screen depending on the environment light. | | 🚫 | 🚫 | ✅ | 🚫 | 🚫 | 🚫 | 🚫 |
Expand Down
16 changes: 16 additions & 0 deletions src/main/rules/GCI95/GCI95.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title": "Use 'is' operator instead of 'as' operator and null check",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant/Issue",
"constantCost": "1min"
},
"tags": [
"roslynator",
"readability",
"simplification",
"performance"
],
"defaultSeverity": "Minor"
}
53 changes: 53 additions & 0 deletions src/main/rules/GCI95/csharp/GCI95.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Using the `as` operator followed by a null check is more verbose and can be simplified using the `is` operator with pattern matching.

When using the `is` pattern, the type check and cast happen in one concise statement, improving readability and reducing boilerplate.

Therefore, using `is` with pattern matching will simplify code and improve maintainability.

== Non compliant Code Example

[source,csharp]
----
var myObj = obj as MyType;
if (myObj != null)
{
myObj.DoSomething();
}
----

== Compliant Code Example

[source,csharp]
----
if (obj is MyType myObj)
{
myObj.DoSomething();
}
----

[source,csharp]
----
var anotherObj = maybeObj as AnotherType;
if (anotherObj != null)
{
Console.WriteLine(anotherObj.Value);
}
----

== Compliant Code Example

[source,csharp]
----
if (maybeObj is AnotherType anotherObj)
{
Console.WriteLine(anotherObj.Value);
}
----
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add some references to prove this rule ? web pages ou local performance tests ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I've added links to the relevant documentation in the rules.json as well as additional notes in this document. The rule was provided from https://github.com/green-code-initiative/creedengo-csharp/blob/main/Rules%20to%20work%20on.md


== Additional Notes

- Pattern matching avoids redundant null checks.
- It ensures the cast object is both non-null and of the expected type.
- It promotes safer and more modern C# practices introduced in C# 7.0 and later.
- Also in [certain cases](https://gist.github.com/StanleySweet/cf6a62ddb1db27c4229804f8a706f323) the assembly is better with is less instructions usually means more performance and less energy consumption.