Изменение типа во время выполнения с помощью GenericTypeArgument

Это то, что я пытаюсь получить

(IList<Foo>)listPropertyInfo.GetValue(item)

Вот как я получаю тип Foo

listPropertyInfo.GetValue(item).GetType().GenericTypeArguments[0]

Это то, что я пробовал, но не смог сделать это успешно

Convert.ChangeType(listPropertyInfo.GetValue(item), IList<listPropertyInfo.GetValue(item).GetType().GenericTypeArguments[0]>)

а также это;

((typeof(IList<>).MakeGenericType(listPropertyInfo.GetValue(item).GetType().GenericTypeArguments.Single())))(listPropertyInfo.GetValue(item))

это метод, в котором я пытаюсь реализовать

public static void trigger(IList<T> result)
{
    foreach (var item in result)
    {
        foreach (var listPropertyInfo in typeof(T).GetProperties().ToList().FindAll(x => x.PropertyType.Name == typeof(IList<>).Name))
        {
             trigger((IList<Foo>)listPropertyInfo.GetValue(item));
        }
    }
}

Ответ 1

Я решил так:

IList targetList = (IList)listPropertyInfo.GetValue(item);
Type foo = targetList.GetType().GenericTypeArguments.Single();
Type unboundGenericType = typeof(READ<>);
Type boundGenericType = unboundGenericType.MakeGenericType(foo);
MethodInfo doSomethingMethod = boundGenericType.GetMethod("trigger");
object instance = Activator.CreateInstance(boundGenericType);
doSomethingMethod.Invoke(instance, new object[] { targetList, f, properties });

Ответ 2

Если вы используете нотацию IList, Foo необходимо определить во время компиляции, вы не можете использовать выражение, которое оценивается во время выполнения для Foo.

Ответ 3

Прочитав ваши комментарии и код, я бы сказал, что вы пытаетесь сделать это не в том месте.

Вот пример того, как вы могли это сделать

public class MyGeneric<T>
{
    public static void trigger(IList<T> result)
    {
        // do generic stuff where
        // you do not need to know T
    }
}

// this class does only explicit Foo related stuff
public class MyNONEGeneric 
{
    public static void trigger(IList<Foo> list)
    {
         // do some 
    }
}


class Program
{
    static void Main(string[] args)
    {
        PersistentGenericBag<Foo> magicBag = myMagic<Foo>();

         // call your generic which do some general list related stuff
         MyGeneric<Foo>.trigger(list);

         // call your none generic which do some foo related stuff
         MyNONEGeneric.trigger(list);
    }
}

как вы можете видеть, я сделал какое-то "разделение проблем" / "принцип единой ответственности" здесь. Каждая вещь делает только "одну" вещь. поэтому, если вам нужно что-то изменить, вы точно узнаете где.

Также, если вы работаете в команде, вы можете сказать Person A, чтобы сделать MyGeneric<T> и Person B, чтобы сделать MyNONEGeneric