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.On This Page