使用GenericTypeArgument在运行时更改类型

时间:2015-06-06 15:32:36

标签: c# generics

这就是我想要的

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

3 个答案:

答案 0 :(得分:3)

我这样解决了;

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

答案 1 :(得分:0)

如果使用IList表示法,必须在编译时定义Foo,不能使用在运行时为Foo计算的表达式。

答案 2 :(得分:0)

在阅读你的评论和代码之后,我会争辩说你正试图在错误的地方做这件事。

这是一个如何做到这一点的例子

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

就像你可以看到我做了一些&#34;关注的分离&#34; /&#34;单一责任原则&#34;这里。 每件事只做&#34;一个&#34;事情。因此,如果您需要更改某些内容,您将确切知道在哪里。

此外,如果您在团队中工作,您可以告诉人员A 执行MyGeneric<T>人员B 来执行MyNONEGeneric < / p>