【问题标题】:Casting an IEnumerable to IEnumerable<T> with reflection使用反射将 IEnumerable 强制转换为 IEnumerable<T>
【发布时间】:2014-10-28 01:03:34
【问题描述】:

所以,我需要调用具有这样签名的第三方方法

ThirdPartyMethod&lt;T&gt;(IEnumerable&lt;T&gt; items)

我的问题是我在编译时不知道我的对象的类型。

在编译时我有这个

IEnumerable myObject;
Type typeOfEnumerableIHave;

Sooo..反射能以某种方式帮助我吗?

为了简单起见,假设我有这样的方法

void DoWork(IEnumerable items, Type type)
{
   //In here I have to call ThirdPartyMethod<T>(IEnumerable<T> items);
}

【问题讨论】:

  • 这个IEnumerable myObject;是在什么情况下出现的?你能多展示一点你的代码吗?
  • @BrunoLM 我已经添加了一些,我不确定它是否会有所帮助

标签: c# reflection ienumerable


【解决方案1】:

既然你有IEnumerable myObject;ThirdPartyMethod&lt;T&gt;(IEnumerable&lt;T&gt; items) 这样的签名,你就可以使用Cast()

ThirdPartyMethod(myObject.Cast<T>())

如果您在编译时不知道 T 类型,您应该在运行时提供它。

假设你的第三方库看起来像这样

public static class External
{
    public static void ThirdPartyMethod<T>(IEnumerable<T> items)
    {
        Console.WriteLine(typeof(T).Name);
    }
}

如果你有关注

Type theType = typeof(int); 
IEnumerable myObject = new object[0];

您可以在运行时获取泛型方法ThirdPartyMethodCast

var targetMethod = typeof(External).GetMethod("ThirdPartyMethod", BindingFlags.Static | BindingFlags.Public);
var targetGenericMethod = targetMethod.MakeGenericMethod(new Type[] { theType });

var castMethod = typeof(Enumerable).GetMethod("Cast", BindingFlags.Static | BindingFlags.Public);
var caxtGenericMethod = castMethod.MakeGenericMethod(new Type[] { theType });

最后你调用了方法:

targetGenericMethod.Invoke(null, new object[] { caxtGenericMethod.Invoke(null, new object[] { myObject }) });

【讨论】:

  • 我不知道正确的表达方式,但我无法访问&lt;T&gt;,我只有Type ..如果这有意义的话
  • @KyleGobel 扩展了我的答案,以展示如何动态解析泛型方法。
  • 太棒了,谢谢,我什至没有想到用这样的反射调用第三方方法
【解决方案2】:

你可以试试这样的:

void DoWork(IEnumerable items, Type type)
    {
        // instance of object you want to call
        var thirdPartyObject = new ThirdPartyObject();
        // create a list with type "type"
        var typeOfList = typeof(List<>).MakeGenericType(type);
        // create an instance of the list and set items 
        // as constructor parameter
        var listInstance = Activator.CreateInstance(listOfTypes, items);
        // call the 3. party method via reflection, make it generic and
        // provide our list instance as parameter
        thirdPartyObject.GetType().GetMethod("ThirdPartyMethod")
            .MakeGenericMethod(type)
            .Invoke(thirdPartyObject, new []{listInstance});            
    }

代码创建泛型类型“type”的列表实例(通过使用 MakeGenericType)。然后将您的项目元素复制到列表中,并通过重新选择调用第三方方法(注意“MakeGenericMethod”调用以确保该方法具有与方法参数相同的类型参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2018-08-04
    相关资源
    最近更新 更多