C#idiomatic C#
ca2021fundamentals/code-analysis/quality-rules

Code analysis

CA2021: Don't call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types

Learn about code analysis rule CA2021 - Don't call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types

CA2021 Reliability enabled by default in .NET 10: As warning
Fix is breaking or non-breaking BreakingApplicable languages C# and Visual Basic

Cause

A call to System.Linq.Enumerable.Cast(System.Collections.IEnumerable)](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.cast--1) or [System.Linq.Enumerable.OfType(System.Collections.IEnumerable) specifies a type parameter that's incompatible with the type of the input collection.

Rule description

System.Linq.Enumerable.Cast(System.Collections.IEnumerable)](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.cast--1) and [System.Linq.Enumerable.OfType(System.Collections.IEnumerable) require compatible types to produce the expected result:

Widening and user-defined conversions aren't supported with generic types.

How to fix violations

Use a compatible type for the type parameter of System.Linq.Enumerable.Cast(System.Collections.IEnumerable)](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.cast--1) and [System.Linq.Enumerable.OfType(System.Collections.IEnumerable).

Example

The following code snippet shows violations:

csharp
var foods = new List<Food>();
// Violation - Food is incompatible with Beverages.
var drinks = Enumerable.Cast<Beverages>(foods);
// Violation - Food is incompatible with Beverages.
var drinks2 = Enumerable.OfType<Beverages>(foods);

class Food { }
class Bread : Food { }
class Beverages { }
vb
' Violation - Integer is incompatible with String.
Dim a1 = (Array.Empty(Of Integer)()).Cast(Of String)
' Violation - Integer is incompatible with String.
Dim a1 = (Array.Empty(Of Integer)()).OfType(Of String)

The following code snippet shows the fixes:

csharp
var foods = new List<Food>();
// Bread is compatible with Food.
var breads = Enumerable.Cast<Bread>(foods);
// Bread is compatible with Food.
var breads2 = Enumerable.OfType<Bread>(foods);

class Food { }
class Bread : Food { }
class Beverages { }
vb
' Integer is compatible with Object.
Dim a1 = (Array.Empty(Of Integer)()).Cast(Of Object)
' Integer is compatible with Object.
Dim a1 = (Array.Empty(Of Integer)()).OfType(Of Object)

When to suppress warnings

You shouldn't suppress warnings from this rule, as you'll either encounter runtime exceptions or unexpected behavior (empty sequences).