Как я могу выполнить метод с типом <T>против итерации типов? - PullRequest
0 голосов
/ 25 октября 2019

Извините за нечетную формулировку вопроса. Я понимаю концепцию, но сегодня у меня нет навыков работы с Google. Любой передаваемый класс унаследует класс «BaseProduct». Это позволяет мне писать код, подобный следующему:

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

Я просто хочу сделать 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?>();
}

Это даже не близко. Спасибо

Редактировать: я не считаю, что это дубликат, потому что есть предположение, что я пытаюсь вызвать метод во всех классах типа. Нет, я пытаюсь вызвать метод для всех производных типов для одного метода.

Ответы [ 3 ]

1 голос
/ 25 октября 2019

Вы можете найти все классы-потомки и затем вызвать универсальный метод следующим образом:

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

Редактировать: Небольшая оптимизация.

1 голос
/ 25 октября 2019

Вы можете сделать следующее:

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
{
}
0 голосов
/ 25 октября 2019

Я думаю, что вы ищете 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...