public static List <Type> FindTypes(TypeConstraintContext constraint)
        {
#if UNITY_2019_2_OR_NEWER
            var parentType = constraint.TargetType;
            var typesCache = TypeCache.GetTypesDerivedFrom(parentType);
            var typesList  = typesCache.ToList();
            typesList.Add(parentType);
            for (var i = typesList.Count - 1; i >= 0; i--)
            {
                var type = typesList[i];
                if (constraint.IsSatisfied(type))
                {
                    continue;
                }

                typesList.RemoveAt(i);
            }
#else
            var typesList  = new List <Type>();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var assembly in assemblies)
            {
                typesList.AddRange(FindTypes(constraint, assembly));
            }

            typesList.Sort((a, b) => a.FullName.CompareTo(b.FullName));
#endif
            return(typesList);
        }
        public static List <Type> FindTypes(TypeConstraintContext constraint, Assembly assembly)
        {
            var types = new List <Type>();

            foreach (var type in assembly.GetTypes())
            {
                if (!constraint.IsSatisfied(type))
                {
                    continue;
                }

                types.Add(type);
            }

            return(types);
        }
        public static TypesCachedCollection GetCollection(TypeConstraintContext constraint)
        {
            var key = constraint.GetHashCode();

            if (cachedCollections.TryGetValue(key, out var collection))
            {
                return(collection);
            }

            var parentType = constraint.TargetType;

            if (parentType == null)
            {
                return(new TypesCachedCollection());
            }

            var typesList = FindTypes(constraint);

            return(cachedCollections[key] = new TypesCachedCollection(typesList));
        }