You can use custom attributes:
using System;
using System.Linq;
using System.Reflection;
namespace ConsoleApp10
{
abstract class Abstract {}
[MaxSpeed(10)]
class ClassA : Abstract {}
[MaxSpeed(20)]
class ClassB : Abstract {}
internal class MaxSpeedAttribute : Attribute
{
public int MaxSpeed { get; }
public MaxSpeedAttribute(int maxSpeed)
{
MaxSpeed = maxSpeed;
}
}
class Program
{
static void Main(string[] args)
{
var candidates = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(Abstract)))
.Select(t => (type: t, maxSpeedAtt: t.GetCustomAttribute<MaxSpeedAttribute>()))
.Where(t => t.maxSpeedAtt != null);
var candidate = candidates.FirstOrDefault(c => c.maxSpeedAtt.MaxSpeed > 4);
var myClass = (Abstract)Activator.CreateInstance(candidate.type);
}
}
}

Note This will fail if the class does not have a parameterless constructor. It will also fail if no classes that extend Abstract
declare the attribute.
Also bear in mind if your classes are in other assemblies you will need to scan those instead of Assembly.GetExecutingAssembly().GetTypes()
I will leave it up to you to come up with the selection logic that you desire.