如何调用List的扩展方法“ElementAt”带有反射?

发布于 2024-08-16 08:12:32 字数 765 浏览 5 评论 0原文

我遇到的问题是,在创建 List < 类型的对象“oListType01”后我的班级01将其分配给“object”类型的另一个对象“oObjectType”后,我无法再访问任何函数“ElementAt(1)”。我尝试使用反射,但我总是在“Invoke”方法中遇到异常(参数冲突)。有谁知道为什么? Milan

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;

从这里开始,只有对象 oObjectType 可用(在实际情况下,向上发生在单独的函数调用中)。在 VS oObjectType 中显示了我想通过反射访问的两个元素。

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

I have problem that after creating object "oListType01" of type List < MyClass01 > and after assigning it to the another objet "oObjectType " of type "object" I can not access any more function "ElementAt(1)". I tried by using reflection but I am always getting exception(parameter conflict) in "Invoke" method. Does anyone knows why ?
Milan

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;

From here fowrads only object oObjectType is available (upwards happens in separate function call in the real case). In VS oObjectType shows two element which I would like to access per reflection.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝颜夕 2024-08-23 08:12:32

我假设你有充分的理由这样做,但这似乎有点错误。也就是说,这里有一些代码可以完成您想要做的事情。

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

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

I will assume you have a valid reason to be doing this but it seems a little wrong. That said here is some code that will accomplish what you are trying to do.

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

When I run this code I get the second element in the List.

梦初启 2024-08-23 08:12:32

ElementAt 扩展方法可能位于 IEnumerable上。因此,当您将列表视为对象时,扩展方法将不可用,除非您强制转换它。 ((List)oObjectType).ElementAt() 或 (oObjectType as List).ElementAt()。

不过,我不得不问,出于应有的尊重,你为什么要首先这样做?让我惊讶的是,这里有一些问题,可以使用接口来完成得更干净一些。

The ElementAt extension method is probably on IEnumerable<T> and so when you treat your list like an object, the extension method won't be available unless you cast it. Either ((List<MyClass01>)oObjectType).ElementAt() or (oObjectType as List<MyClass01>).ElementAt().

I have to ask, though, with all due respect why you'd ever want to do this in the first place? It strikes me that there's something wrong here that could be done a little cleaner using interfaces.

自由如风 2024-08-23 08:12:32

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

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

If we can safely assume that:

  • oObjectType is a IEnumerable of some T

then here's the code to extract the items from it.

Note that I seriously wonder if this is the right way to go about this, but you haven't given us enough information to help you figure out if there's a better way, so all we're left with is just answering the question as asked.

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 }));
        }
    }
}
岛歌少女 2024-08-23 08:12:32

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

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

This is really similar to your other question, but in this case, the static ElementAt method is actually requiring two parameters. Try this:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文