|
| 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). |
0 commit comments