84 lines
2.5 KiB
Plaintext
Raw Permalink Normal View History

== Why is this an issue?
2023-06-15 10:20:09 +02:00
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sum[Enumerable.Sum()] always executes addition in a `checked` context, so an https://learn.microsoft.com/en-us/dotnet/api/system.overflowexception[OverflowException] will be thrown if the value exceeds `MaxValue`, even if an `unchecked` context was specified. Therefore, using this method inside an `unchecked` context will only make the code more confusing, since the behavior will still be `checked`.
2021-04-28 16:49:39 +02:00
2023-06-15 10:20:09 +02:00
This rule raises an issue when an `unchecked` context is specified for a `Sum` on integer types.
2021-04-28 16:49:39 +02:00
2023-06-15 10:20:09 +02:00
=== Exceptions
2023-06-15 10:20:09 +02:00
When the `Sum` call is inside a https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/exceptions/[try-catch block], no issues are reported, since the exception is properly handled.
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,csharp]
2021-04-28 16:49:39 +02:00
----
void Add(List<int> list)
{
unchecked
{
2023-06-15 10:20:09 +02:00
try
{
int total = list.Sum();
}
catch (System.OverflowException e)
{
// Exception handling
}
2021-04-28 16:49:39 +02:00
}
}
----
2023-06-15 10:20:09 +02:00
== How to fix it
2021-04-28 16:49:39 +02:00
2023-06-15 10:20:09 +02:00
Remove the `unchecked` operator/statement, and optionally add some exception handling for the `OverflowException`.
=== Code examples
==== Noncompliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
2021-04-28 16:49:39 +02:00
----
void Add(List<int> list)
{
2023-06-15 10:20:09 +02:00
int total1 = unchecked(list.Sum()); // Noncompliant
2021-04-28 16:49:39 +02:00
2023-06-15 10:20:09 +02:00
unchecked
2021-04-28 16:49:39 +02:00
{
2023-06-15 10:20:09 +02:00
int total2 = list.Sum(); // Noncompliant
2021-04-28 16:49:39 +02:00
}
}
----
2023-06-15 10:20:09 +02:00
==== Compliant solution
2021-04-28 16:49:39 +02:00
2023-06-15 10:20:09 +02:00
[source,csharp,diff-id=1,diff-type=compliant]
2021-04-28 16:49:39 +02:00
----
void Add(List<int> list)
{
2023-06-15 10:20:09 +02:00
int total1 = list.Sum();
try
2021-04-28 16:49:39 +02:00
{
2023-06-15 10:20:09 +02:00
int total2 = list.Sum();
}
catch (System.OverflowException e)
{
// Exception handling
2021-04-28 16:49:39 +02:00
}
}
----
2023-06-15 10:20:09 +02:00
== Resources
2023-06-15 10:20:09 +02:00
=== Documentation
2023-06-15 10:20:09 +02:00
* https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sum[`Enumerable.Sum` Method]
* https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/System.Core/System/Linq/Enumerable.cs#L1408-L1415[`Enumerable.Sum` implementation]
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/checked-and-unchecked[`checked` and `unchecked` statements]
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#12819-the-checked-and-unchecked-operators[`checked` and `unchecked` operators]
* https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/exceptions/[Exceptions and Exception Handling]
* https://learn.microsoft.com/en-us/dotnet/api/system.overflowexception[`OverflowException` Class]
* https://en.wikipedia.org/wiki/Integer_overflow[Integer overflow]
2023-06-15 10:20:09 +02:00
include::../rspecator.adoc[]