如何使用反射调用List <t>的扩展方法“ElementAt”?</t>

时间:2009-12-22 19:11:44

标签: c# linq reflection extension-methods

我在创建List&lt;类型的对象“oListType01”后遇到了问题。 MyClass01&gt;并且在将其分配给另一个类型为“object”的objet“oObjectType”之后,我无法访问任何更多的函数“ElementAt(1)”。我尝试使用反射,但我总是在“调用”方法中获得异常(参数冲突)。有谁知道为什么? 米兰

MyClass01 oMy1 = new MyClass01();
oMy1._ID = "1";

MyClass01 oMy2 = new MyClass01();
oMy2._ID = "3";

IList<MyClass01> oListType01 = new List<MyClass01>();

oListType01.Add(oMy1);
oListType01.Add(oMy2);

object oObjectType = new object();

oObjectType = oListType01;

从这里fowrads只有对象oObjectType可用(在实际情况下向上发生在单独的函数调用中)。在VS oObjectType中显示了我想要反映的两个元素。

MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("ElementAt").MakeGenericMethod(typeof(object));
object oSingleObject = mInfo.Invoke(oObjectType, new object[] { 1 });

4 个答案:

答案 0 :(得分:9)

我会假设你有正当理由这样做,但似乎有点不对劲。这里说的是一些能够完成你想要做的事情的代码。

MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("ElementAt").MakeGenericMethod(typeof(MyClass01));
object oSingleObject = mInfo.Invoke(oObjectType, new object[] { oObjectType, 1 });

当我运行此代码时,我得到List中的第二个元素。

答案 1 :(得分:0)

ElementAt扩展方法可能在IEnumerable&lt; T&gt;上了。因此,当您将列表视为对象时,除非您进行转换,否则扩展方法将不可用。 ((List&lt; MyClass01&gt;)oObjectType).ElementAt()或(oObjectType as List&lt; MyClass01&gt;)。ElementAt()。

但是,我必须要问,为什么你一开始就想要这样做呢?我觉得这里有一些错误,使用接口可以做得更清洁。

答案 2 :(得分:0)

如果我们可以安全地假设:

  • oObjectType是某些T
  • 的IEnumerable

然后这是从中提取项目的代码。

请注意,我真的很想知道这是否是正确的方式,但你没有给我们足够的信息来帮助你弄清楚是否有更好的方法,所以我们所有的'留下来就是回答问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;

namespace ConsoleApplication2
{
    class MyClass01
    {
        public String _ID;

        public override string ToString()
        {
            return _ID;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass01 oMy1 = new MyClass01();
            oMy1._ID = "1";

            MyClass01 oMy2 = new MyClass01();
            oMy2._ID = "3";

            IList<MyClass01> oListType01 = new List<MyClass01>();

            oListType01.Add(oMy1);
            oListType01.Add(oMy2);

            object oObjectType = new object();

            oObjectType = oListType01;

            Test(oObjectType);

            Console.In.ReadLine();
        }

        private static void Test(object oObjectType)
        {
            Type tObject = oObjectType.GetType();
            Debug.Assert(tObject.IsGenericType);
            Debug.Assert(tObject.GetGenericArguments().Length == 1);
            Type t = tObject.GetGenericArguments()[0];

            Type tIEnumerable = typeof(IEnumerable<>).MakeGenericType(t);
            Debug.Assert(tIEnumerable.IsAssignableFrom(tObject));

            MethodInfo mElementAt =
                typeof(Enumerable)
                .GetMethod("ElementAt")
                .MakeGenericMethod(t);

            Console.Out.WriteLine("o[0] = " +
                mElementAt.Invoke(null, new Object[] { oObjectType, 0 }));
            Console.Out.WriteLine("o[1] = " +
                mElementAt.Invoke(null, new Object[] { oObjectType, 1 }));
        }
    }
}

答案 3 :(得分:0)

这与您的other question非常相似,但在这种情况下,静态ElementAt方法实际上需要两个参数。试试这个:

object oSingleObject = mInfo.Invoke(null,new object [] {oObjectType,1});