Skip to content

Commit 02767ff

Browse files
authored
Add CA2021 (#38286)
1 parent 6ad9a86 commit 02767ff

File tree

5 files changed

+93
-3
lines changed

5 files changed

+93
-3
lines changed

docs/fundamentals/code-analysis/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ The following rules are enabled, by default, in .NET 8.
4848
| [CA2015](quality-rules/ca2015.md) | Reliability | Warning | Do not define finalizers for types derived from <xref:System.Buffers.MemoryManager%601> |
4949
| [CA2017](quality-rules/ca2017.md) | Reliability | Warning | Parameter count mismatch |
5050
| [CA2018](quality-rules/ca2018.md) | Reliability | Warning | The `count` argument to `Buffer.BlockCopy` should specify the number of bytes to copy |
51+
| [CA2021](quality-rules/ca2021.md) | Reliability | Warning | Do not call `Enumerable.Cast<T>` or `Enumerable.OfType<T>` with incompatible types |
5152
| [CA2200](quality-rules/ca2200.md) | Usage | Warning | Rethrow to preserve stack details |
52-
| CA2021 | Reliability | Warning | Do not call `Enumerable.Cast<T>` or `Enumerable.OfType<T>` with incompatible types |
5353
| [CA2247](quality-rules/ca2247.md) | Usage | Warning | Argument passed to `TaskCompletionSource` constructor should be <xref:System.Threading.Tasks.TaskCreationOptions> enum instead of <xref:System.Threading.Tasks.TaskContinuationOptions> |
5454
| [CA2252](quality-rules/ca2252.md) | Usage | Error | Opt in to preview features |
5555
| [CA2255](quality-rules/ca2255.md) | Usage | Warning | The `ModuleInitializer` attribute should not be used in libraries |
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: "CA2021: Don't call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types"
3+
description: "Learn about code analysis rule CA2021 - Don't call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types"
4+
ms.date: 11/16/2023
5+
f1_keywords:
6+
- CA2021
7+
helpviewer_keywords:
8+
- CA2021
9+
dev_langs:
10+
- CSharp
11+
- VB
12+
---
13+
# CA2021: Don't call Enumerable.Cast\<T> or Enumerable.OfType\<T> with incompatible types
14+
15+
| Property | Value |
16+
|-------------------------------------|--------------------------------------------------------------------------|
17+
| **Rule ID** | CA2021 |
18+
| **Title** | Don't call `Enumerable.Cast<T>` or `Enumerable.OfType<T>` with incompatible types |
19+
| **Category** | [Reliability](reliability-warnings.md) |
20+
| **Fix is breaking or non-breaking** | Breaking |
21+
| **Enabled by default in .NET 8** | Yes |
22+
23+
## Cause
24+
25+
A call to <xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> or <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> specifies a type parameter that's incompatible with the type of the input collection.
26+
27+
## Rule description
28+
29+
<xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> and <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> require compatible types to produce the expected result:
30+
31+
- The generic cast used by the sequence returned by <xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)> throws an <xref:System.InvalidCastException> at run time on elements of incompatible types.
32+
- The generic type check used by <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)> won't succeed with elements of incompatible types, resulting in an empty sequence.
33+
34+
Widening and user-defined conversions aren't supported with generic types.
35+
36+
## How to fix violations
37+
38+
Use a compatible type for the type parameter of <xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)> and <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)>.
39+
40+
## Example
41+
42+
The following code snippet shows violations:
43+
44+
```csharp
45+
var foods = new List<Food>();
46+
// Violation - Food is incompatible with Beverages.
47+
var drinks = Enumerable.Cast<Beverages>(foods);
48+
// Violation - Food is incompatible with Beverages.
49+
var drinks2 = Enumerable.OfType<Beverages>(foods);
50+
51+
class Food { }
52+
class Bread : Food { }
53+
class Beverages { }
54+
```
55+
56+
```vb
57+
' Violation - Integer is incompatible with String.
58+
Dim a1 = (Array.Empty(Of Integer)()).Cast(Of String)
59+
' Violation - Integer is incompatible with String.
60+
Dim a1 = (Array.Empty(Of Integer)()).OfType(Of String)
61+
```
62+
63+
The following code snippet shows the fixes:
64+
65+
```csharp
66+
var foods = new List<Food>();
67+
// Bread is compatible with Food.
68+
var breads = Enumerable.Cast<Bread>(foods);
69+
// Bread is compatible with Food.
70+
var breads2 = Enumerable.OfType<Bread>(foods);
71+
72+
class Food { }
73+
class Bread : Food { }
74+
class Beverages { }
75+
```
76+
77+
```vb
78+
' Integer is compatible with Object.
79+
Dim a1 = (Array.Empty(Of Integer)()).Cast(Of Object)
80+
' Integer is compatible with Object.
81+
Dim a1 = (Array.Empty(Of Integer)()).OfType(Of Object)
82+
```
83+
84+
## When to suppress warnings
85+
86+
You shouldn't suppress warnings from this rule, as you'll either encounter run-time exceptions or unexpected behavior (empty sequences).

docs/fundamentals/code-analysis/quality-rules/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Code quality rules overview
33
description: Learn about all of the available code quality rules for code analysis.
4-
ms.date: 09/01/2020
4+
ms.date: 11/16/2023
55
author: mikadumont
66
ms.author: midumont
77
---
@@ -179,6 +179,7 @@ The following table lists code quality analysis rules.
179179
> | [CA2018: The `count` argument to `Buffer.BlockCopy` should specify the number of bytes to copy](ca2018.md) | When using `Buffer.BlockCopy`, the `count` argument specifies the number of bytes to copy. You should only use `Array.Length` for the `count` argument on arrays whose elements are exactly one byte in size. `byte`, `sbyte`, and `bool` arrays have elements that are one byte in size. |
180180
> | [CA2019: `ThreadStatic` fields should not use inline initialization](ca2019.md) | A field that's annotated with <xref:System.ThreadStaticAttribute> is initialized inline or explicitly in a `static` (`Shared` in Visual Basic) constructor. |
181181
> | [CA2020: Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr](ca2020.md) | Some built-in operators added in .NET 7 behave differently than the user-defined operators in .NET 6 and earlier versions. Some operators that used to throw in unchecked context while overflowing don't throw anymore unless wrapped within checked context. Some operators that previously didn't throw in checked context now throw unless wrapped within unchecked context. |
182+
> | [CA2021: Don't call Enumerable.Cast\<T> or Enumerable.OfType\<T> with incompatible types](ca2021.md) | A call to <xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> or <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> specifies a type parameter that's incompatible with the type of the input collection. |
182183
> | [CA2100: Review SQL queries for security vulnerabilities](ca2100.md) | A method sets the System.Data.IDbCommand.CommandText property by using a string that is built from a string argument to the method. This rule assumes that the string argument contains user input. A SQL command string that is built from user input is vulnerable to SQL injection attacks. |
183184
> | [CA2101: Specify marshalling for P/Invoke string arguments](ca2101.md) | A platform invoke member allows partially trusted callers, has a string parameter, and does not explicitly marshal the string. This can cause a potential security vulnerability. |
184185
> | [CA2109: Review visible event handlers](ca2109.md) | A public or protected event-handling method was detected. Event-handling methods should not be exposed unless absolutely necessary. |

docs/fundamentals/code-analysis/quality-rules/reliability-warnings.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Reliability rules (code analysis)
33
description: "Learn about code analysis reliability rules."
4-
ms.date: 11/04/2016
4+
ms.date: 11/16/2023
55
f1_keywords:
66
- vs.codeanalysis.reliabilityrules
77
helpviewer_keywords:
@@ -32,3 +32,4 @@ Reliability rules support library and application reliability, such as correct m
3232
| [CA2018: The `count` argument to `Buffer.BlockCopy` should specify the number of bytes to copy](ca2018.md) | When using `Buffer.BlockCopy`, the `count` argument specifies the number of bytes to copy. You should only use `Array.Length` for the `count` argument on arrays whose elements are exactly one byte in size. `byte`, `sbyte`, and `bool` arrays have elements that are one byte in size. |
3333
| [CA2019: `ThreadStatic` fields should not use inline initialization](ca2019.md) | A field that's annotated with <xref:System.ThreadStaticAttribute> is initialized inline or explicitly in a `static` (`Shared` in Visual Basic) constructor. |
3434
| [CA2020: Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr](ca2020.md) | Some built-in operators added in .NET 7 behave differently than the user-defined operators in .NET 6 and earlier versions. Some operators that used to throw in unchecked context while overflowing don't throw anymore unless wrapped within checked context. Some operators that previously didn't throw in checked context now throw unless wrapped within unchecked context. |
35+
| [CA2021: Don't call Enumerable.Cast\<T> or Enumerable.OfType\<T> with incompatible types](ca2021.md) | A call to <xref:System.Linq.Enumerable.Cast%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> or <xref:System.Linq.Enumerable.OfType%60%601(System.Collections.IEnumerable)?displayProperty=nameWithType> specifies a type parameter that's incompatible with the type of the input collection. |

docs/navigate/tools-diagnostics/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,8 @@ items:
10631063
href: ../../fundamentals/code-analysis/quality-rules/ca2019.md
10641064
- name: CA2020
10651065
href: ../../fundamentals/code-analysis/quality-rules/ca2020.md
1066+
- name: CA2021
1067+
href: ../../fundamentals/code-analysis/quality-rules/ca2021.md
10661068
- name: Security rules
10671069
items:
10681070
- name: Overview

0 commit comments

Comments
 (0)