Filter IEnumerable with OfType

LINQ has a built in method to automatically filter a collection by a specific Type

Home DailyDrop

Daily Knowledge Drop

LINQ provides a built in method to filter collection contents by type, OfType<>. This is considerably easier and more streamline than the alternative of using a Where in combination with a Select (which I had previously been using)


Setup

In the below example, the setup is as follows:

We have three interfaces:

public interface IBaseType {}

public interface ITypeA
{
    void ExecuteTypeAProcessing();
}

public interface ITypeB
{
    void ExecuteTypeBProcessing();
}

And two classes which implement these interfaces:

// implement the base interface and TypeA interface
public class TypeA : IBaseType, ITypeA
{
    public void ExecuteTypeAProcessing()
    {
        Console.WriteLine($"{nameof(ExecuteTypeAProcessing)} has been called");
    }
}

// implement the base interface and TypeB interface
public class TypeB : IBaseType, ITypeB
{
    public void ExecuteTypeBProcessing()
    {
        Console.WriteLine($"{nameof(ExecuteTypeBProcessing)} has been called");
    }
}

A list of IBaseType has also been initialized, and contains a combination of TypeA and TypeB instances (this is possible, as both types implement IBaseType):

List<IBaseType> types = new()
{
  new TypeA(),
  new TypeA(),
  new TypeB(),
  new TypeA(),
  new TypeB(),
  new TypeB(),
  new TypeA(),
};

Where with Select

This is the method I've been using prior to knowing there was an alternative. It does work, but is very verbose.

Suppose we want to execute the ExecuteTypeAProcessing method on instances of ITypeA:

foreach(var type in types
    .Where(t => t is ITypeA)
    .Select(t => t as ITypeA))
{
    type.ExecuteTypeAProcessing();
}

Another method, this time executing ExecuteTypeBProcessing on instances of ITypeB:

types.Where(t => t is ITypeB)
    .Select(t => t as ITypeB)
    .ToList()
    .ForEach(t => t.ExecuteTypeBProcessing());

OfType

Only recently did I come across the OfType method on IEnumerable - not that it was hidden in any way, I just never looked for it, as the above Where + Select method worked for my needs. However OfType greatly simplifies the above code.

Executing ExecuteTypeAProcessing on instances of ITypeA:

foreach(var type in types.OfType<ITypeA>())
{
    type.ExecuteTypeAProcessing();
}

Executing ExecuteTypeBProcessing on instances of ITypeB:

types.OfType<ITypeB>()
    .ToList()
    .ForEach(t => t.ExecuteTypeBProcessing());

Either option is simpler, more concise and more readable than the Where + Select method.


Notes

Nothing groundbreaking learnt today - but never-the-less something very interesting and useful, which will definitely see frequent usage.


Daily Drop 142: 19-08-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net linq typeof