Search code examples
c#loopsreflectiontypesdefault

How can I execute a method with type <T> against an iteration of types?


Sorry for the odd question wording.. I understand the concept but my google skills are lacking today.

I have a method that allows me to specify a generic to use for its work. Any class that gets passed in will inherit a class of "BaseProduct". This allows me to write code like the following.

SyncProductsByType<PublicationProduct>();
SyncProductsByType<ApparelProduct>();
.... etc

I just want to do a foreach on the basetype's subclasses, but I can't get the syntax right. So far, I have:

Type parentType = typeof(BaseProduct);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
IEnumerable<Type> subclasses = types.Where(t => t.BaseType == parentType);

but thats ALL WRONG for use in a foreach. I can't figure out how to do this sort of thing:

foreach (<T> subclasse yadda yadda) {
    SyncProductsByType<something?>();
}

Thats not even close. Thanks

Edit: I don't believe this is a duplicate because there is an assumption that I'm trying to Invoke a method in all classes of type . No, what I'm trying to do is call a method against all derives types against a single method.


Solution

  • You can find all descendant classes and then invoke the generic method this way:

    class Program
    {
        class BaseClass
        {
            public static void Generic<T>() where T : BaseClass
            {
                Console.WriteLine(typeof(T).Name);
            }
        }
        class FirstClass : BaseClass
        {
    
        }
        class SecondClass : BaseClass
        {
    
        }
        static void Main(string[] args)
        {
            MethodInfo method = typeof(BaseClass).GetMethod("Generic");
    
            foreach (var item in Assembly.GetExecutingAssembly().GetTypes()
                                            .Where(myType => myType.IsClass && myType.IsSubclassOf(typeof(BaseClass))))
            {
                MethodInfo generic = method.MakeGenericMethod(item);
                generic.Invoke(null, null);
            }
        }
    }
    

    Edit: A little optimalization.