user486523
user486523

Reputation:

When to use Cast() and OfType() in Linq

I am aware of two methods of casting types to IEnumerable from an Arraylist in Linq and wondering in which cases to use them?

e.g

IEnumerable<string> someCollection = arrayList.OfType<string>()

or

IEnumerable<string> someCollection = arrayList.Cast<string>()

What is the difference between these two methods and where should I apply each case?

Upvotes: 284

Views: 119287

Answers (7)

Ash
Ash

Reputation: 1984

Source: LINQ Tip: Enumerable.OfType - Solutionizing .NET

Fundamentally, Cast<T>() is implemented like this:

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}

Using an explicit cast performs well, but will result in an InvalidCastException if the cast fails. A less efficient yet useful variation on this idea is OfType<T>():

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T t)
      yield return t;
}

The returned enumeration will only include elements that can safely be cast to the specified type.

Upvotes: 144

Niya
Niya

Reputation: 253

It should be noted that Cast(Of T) can be used on IEnumerable unlike other LINQ functions, so if there's ever a case where you need to use LINQ on a non-generic collection or list such as an ArrayList, you can use Cast(Of T) to cast to an IEnumerable(Of T) where LINQ can work.

Upvotes: 8

Brian Ensink
Brian Ensink

Reputation: 11218

Cast<T> will try to cast all items to the given type T. This cast could fail or throw an exception. OfType<T> will return a subset of the original collection and return only objects that are of type T.

Upvotes: 2

Johann Blais
Johann Blais

Reputation: 9469

OfType will filter the elements to return only the ones of the specified type. Cast will crash if an element cannot be cast to the target type.

Upvotes: 2

Itay Karo
Itay Karo

Reputation: 18286

OfType - return only the elements that can safely be cast to type x.
Cast - will try to cast all the elements into type x. if some of them are not from this type you will get InvalidCastException

EDIT
for example:

object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }

Upvotes: 428

SLaks
SLaks

Reputation: 887453

You should call Cast<string>() if you know that all of the items are strings.
If some of them aren't strings, you'll get an exception.

You should call OfType<string>() if you know that some of the items aren't strings and you don't want those items.
If some of them aren't strings, they won't be in the new IEnumerable<string>.

Upvotes: 51

Andrew Bezzub
Andrew Bezzub

Reputation: 16032

Cast() will try to cast all elements of the collection (and will throw an exception if element is of the wrong type) while OfType() will return only elements of proper type.

Upvotes: 2

Related Questions