1

Consider the following classes:

class A
{
    public virtual string Name { get { return "A"; } }
}

class B : A
{
    public override string Name { get { return "B"; } }
}

class C : A
{
    public override string Name { get { return "C"; } }
}

And a list containing two objects of type B and one of type C:

List<A> l = new List<A>();
l.Add(new B());
l.Add(new C());
l.Add(new B());

Is there some way to force a check of the type at runtime and iterate only over the objects of type B in this list (short of writing a custom implementation of a list)? Something like:

foreach (B obj in l)               // runtime error
    Console.WriteLine(obj.Name);

// desired output:
//   B
//   B

I haven't run into this problem in a project, but the thought just occurred to me and I'm curious if this can be done. I'm aware the need for this feature could indicate a design flaw.

drew.cuthbert
  • 1,005
  • 1
  • 9
  • 21
  • 2
    Check out [`Enumerable.OfType`](https://msdn.microsoft.com/en-us/library/vstudio/bb360913(v=vs.100).aspx) – juharr Aug 03 '15 at 16:56
  • Possible duplicate of [Type Checking: typeof, GetType, or is?](http://stackoverflow.com/questions/983030/type-checking-typeof-gettype-or-is) – Liam Nov 06 '15 at 08:40

2 Answers2

7

You can use .OfType<T>():

foreach (B obj in l.OfType<B>())
    Console.WriteLine(obj.Name);

If you want only Bs, and not any subclasses of B to be listed, you can use the following:

foreach (B obj in l.Where(o => o.GetType() == typeof(B)))
    Console.WriteLine(obj.Name);
Jashaszun
  • 9,207
  • 3
  • 29
  • 57
4
foreach (A obj in l) 
{
    if (obj is B)
    {
       Console.WriteLine(obj.Name);
    }

}
ro-E
  • 279
  • 1
  • 5
  • 16