using System.Collections.Generic;
public static void Main()
List<MyBaseClass> some = [new WithoutName(), new WithoutName(), new WithName(){Name = "Alphonso"}, new WithNameAndNumber(){Name = "Betrand", Number = 42}];
Console.WriteLine("OfType<T> :");
Console.WriteLine(JsonSerializer.Serialize(some.OfType<IHasName>()));
Console.WriteLine("Where IsAssignableTo:");
Console.WriteLine(JsonSerializer.Serialize(some.Where(x => x.GetType().IsAssignableTo(typeof(IHasName))).Select(x => (IHasName)x)));
Console.WriteLine("Where 'is':");
Console.WriteLine(JsonSerializer.Serialize(some.Where(x => x is IHasName).Select(x => (IHasName)x)));
Console.WriteLine("Filter + Visitor");
foreach(var item in some.Where(x => x is IHasName))
item.Visit(x => x.Dump());
Console.WriteLine("Visitor without Filter");
foreach(var item in some)
item.Visit(x => x.Dump());
Console.WriteLine("Filter and cast");
var listOfWithName = some.OfType<WithName>().ToList();
Console.WriteLine(listOfWithName.GetType().Name);
public abstract class MyBaseClass
public virtual void Visit(Action<IHasName> visitor){
public interface IHasName
public sealed class WithName : MyBaseClass, IHasName
public required string Name {get; init;}
public override void Visit(Action<IHasName> visitor){
public sealed class WithNameAndNumber : MyBaseClass, IHasName
public required string Name {get; init;}
public required int Number {get; init;}
public override void Visit(Action<IHasName> visitor){
public sealed class WithoutName : MyBaseClass