Linq
C# programming
Cast()
OfType()
.NET

When to use Cast and OfType in Linq

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Cast and OfType are both LINQ methods used when a sequence needs type conversion behavior, especially from non-generic collections. They look similar, but their failure behavior is different and that difference matters in production code. Use Cast when all elements must be valid for one target type, and use OfType when you want to filter by compatible elements safely.

Core Behavior Difference

Cast<T>():

  • attempts to cast every element to T
  • throws InvalidCastException when any element is incompatible

OfType<T>():

  • returns only elements compatible with T
  • silently skips incompatible elements

That is the main decision point.

Cast<T>() Example

csharp
1using System;
2using System.Collections;
3using System.Linq;
4
5ArrayList values = new ArrayList { 1, 2, 3 };
6
7var ints = values.Cast<int>();
8Console.WriteLine(ints.Sum());

If values later contains a string, enumeration fails with InvalidCastException.

OfType<T>() Example

csharp
1using System;
2using System.Collections;
3using System.Linq;
4
5ArrayList mixed = new ArrayList { 1, "x", 2, null, 3 };
6
7var ints = mixed.OfType<int>();
8Console.WriteLine(string.Join(",", ints));

Output includes only 1,2,3. Non-int values are ignored.

Deferred Execution and Exception Timing

Both methods are deferred. Errors from Cast happen when enumerating, not when building the query.

csharp
1var query = mixed.Cast<int>();
2// no error yet
3foreach (var x in query)
4{
5    Console.WriteLine(x); // exception appears during iteration
6}

This timing can confuse debugging if query composition and execution are separated.

When Cast Is Better

Choose Cast when invalid elements indicate bad data and should fail fast.

Typical cases:

  • strict ETL pipelines
  • trusted collection contracts
  • scenarios where silent filtering would hide defects

Cast makes data quality violations explicit.

When OfType Is Better

Choose OfType when mixed collections are expected and filtering is intentional.

Typical cases:

  • plugin pipelines with heterogeneous payloads
  • UI trees with multiple node types
  • optional feature objects in shared object collections

OfType keeps query flow resilient.

Relationship With Where and Pattern Matching

OfType<T>() can often replace verbose filtering plus casting:

csharp
1var result = mixed
2    .OfType<int>()
3    .Where(x => x > 1)
4    .ToList();

Equivalent explicit style:

csharp
1var result2 = mixed
2    .Where(x => x is int)
3    .Select(x => (int)x)
4    .Where(x => x > 1)
5    .ToList();

Use whichever is clearer for your team style.

Generic Collections Usually Do Not Need Either

For strongly typed collections such as List<int>, neither method is usually necessary. These methods are mainly useful when the source type is weakly typed, for example IEnumerable or IEnumerable<object> from legacy boundaries.

Avoid unnecessary conversions in already typed pipelines.

Performance Considerations

Both methods are lightweight iterators. Performance differences are usually negligible compared to downstream operations. The bigger concern is semantic correctness:

  • do you want strict failure or silent filtering
  • do you want to preserve or reject unexpected elements

Choose by behavior, then profile if needed.

Null Handling Nuance

OfType<T>() skips null for value types and also skips null for reference types when null is not compatible with target filtering behavior. Cast<T>() preserves null for nullable-compatible references until enumeration attempts an invalid cast. Testing with representative null-containing inputs avoids surprises in legacy pipelines. This is especially relevant when migrating from non-generic collections created by older APIs.

Common Pitfalls

  • Using OfType and unintentionally hiding unexpected invalid elements.
  • Using Cast on mixed sequences and encountering runtime exceptions late.
  • Forgetting deferred execution and misplacing error handling.
  • Applying Cast or OfType on already strongly typed collections unnecessarily.
  • Assuming Cast converts values, rather than performing runtime casting only.

Summary

  • 'Cast<T>() enforces strict type compatibility and fails on mismatch.'
  • 'OfType<T>() filters sequence elements to the target type safely.'
  • Use Cast for fail-fast data contracts.
  • Use OfType for expected heterogeneous collections.
  • Decide based on correctness semantics, not syntax preference.

Course illustration
Course illustration

All Rights Reserved.