如何针对类型的迭代执行类型为 <T> 的方法?

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

抱歉奇怪的问题措辞。我理解这个概念,但我今天 google 技能不足。

我有一个方法可以让我指定一个泛型用于它的工作。传入的任何 class 将继承 "BaseProduct" 的 class。这允许我编写如下代码。

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

我只想在基类型的子classes 上做一个 foreach,但我无法获得正确的语法。 到目前为止,我有:

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

但是在 foreach 中使用是完全错误的。我不知道该怎么做:

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

那还差得远。谢谢

编辑: 我不认为这是重复的,因为假设我正在尝试在所有 class 类型的类型中调用一个方法。不,我想做的是针对单个方法调用针对所有派生类型的方法。

您可以执行以下操作:

public class Test
{
    public static void SyncProductsByType<T>() where T : BaseProduct
    {
        // this method is a simple wrapper with constraint

        SyncProductsByType(typeof(T));
    }

    public static void SyncProductsByType(Type type)
    {
        // decide whether this should public, private or internal

        if (type.BaseType != typeof(BaseProduct))
            throw new ArgumentOutOfRangeException(nameof(type));

        // do work
    }
}

public abstract class BaseProduct
{
}

public class ApparelProduct : BaseProduct
{
}

您可以找到所有后代 类,然后以这种方式调用泛型方法:

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);
        }
    }
}

编辑: 稍微优化一下。

我想你要找的是 Type.IsSubclassOf 这个检查一个类型是否是另一个类型的子类。使用所述 Type 对象调用方法的唯一方法是获取通用定义 MethodInfo,然后使用 MakeGenericMethod 创建一个通用方法,该方法将 T 设置为指定的Type,例如:

Type parentType = typeof(BaseProduct);

Assembly assembly = Assembly.GetExecutingAssembly();

Type[] types = assembly.GetTypes();

var genericDefinition = typeof(BaseClass).GetMethod("SyncProductsByType");

foreach (Type type in types)
{
    if (type.IsSubclassOf(parentType))
    {
        genericDefinition.MakeGenericMethod(type).Invoke(instance, null);
    }
}